Je veux lire un fichier octet par octet et vérifier si le dernier bit de chaque octet est défini:
#!/usr/bin/python
def main():
fh = open('/tmp/test.txt', 'rb')
try:
byte = fh.read(1)
while byte != "":
if (int(byte,16) & 0x01) is 0x01:
print 1
else:
print 0
byte = fh.read(1)
finally:
fh.close
fh.close()
if __name__ == "__main__":
main()
L'erreur que j'obtiens est:
Traceback (most recent call last):
File "./mini_01.py", line 21, in <module>
main()
File "./mini_01.py", line 10, in main
if (int(byte,16) & 0x01) is 0x01:
ValueError: invalid literal for int() with base 16: '\xaf'
Quelqu'un a une idée? Je n'ai pas réussi à utiliser la structure et les modules binascii.
Vous souhaitez utiliser ord
au lieu de int
:
if (ord(byte) & 0x01) == 0x01:
Essayez d'utiliser le type bytearray
(Python 2.6 et versions ultérieures), il est beaucoup mieux adapté au traitement des données d'octets. Votre bloc try
serait simplement:
ba = bytearray(fh.read())
for byte in ba:
print byte & 1
ou pour créer une liste de résultats:
low_bit_list = [byte & 1 for byte in bytearray(fh.read())]
Cela fonctionne parce que lorsque vous indexez un bytearray
vous récupérez simplement un entier (0-255), tandis que si vous venez de lire un octet du fichier, vous récupérez une chaîne de caractères unique et devez donc utiliser ord
pour le convertir en entier.
Si votre fichier est trop volumineux pour être conservé confortablement en mémoire (même si je suppose que ce n'est pas le cas), alors un mmap
pourrait être utilisé pour créer le bytearray
à partir de un tampon:
import mmap
m = mmap.mmap(fh.fileno(), 0, access=mmap.ACCESS_READ)
ba = bytearray(m)
Une manière:
import array
filebytes= array.array('B')
filebytes.fromfile(open("/tmp/test.txt", "rb"))
if all(i & 1 for i in filebytes):
# all file bytes are odd
Autrement:
fobj= open("/tmp/test.txt", "rb")
try:
import functools
except ImportError:
bytereader= lambda: fobj.read(1)
else:
bytereader= functools.partial(fobj.read, 1)
if all(ord(byte) & 1 for byte in iter(bytereader, '')):
# all bytes are odd
fobj.close()