je cherche à lire différents fichiers binaires dont je connais le
format.
Pour les reconnaitre, j'ai besoin de lire quelques octets, puis
de les vérifier, et selon les cas d'en lire plus ou moins ensuite,
etc..
Je pense a une fonction "walker" qui me lit le fichier octet après
octet et itérer mais n'y a t'il pas un moyen simple de lire des
séquences d'octets à des zones arbitraires du fichier?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Damien Wyart
* Kevin Denis in fr.comp.lang.python:
je cherche à lire différents fichiers binaires dont je connais le format. Pour les reconnaitre, j'ai besoin de lire quelques octets, puis de les vérifier, et selon les cas d'en lire plus ou moins ensuite, etc..
Sur ce thème, il y a pas mal de choses sur StackOverflow :
Je pense a une fonction "walker" qui me lit le fichier octet après octet et itérer mais n'y a t'il pas un moyen simple de lire des séquences d'octets à des zones arbitraires du fichier?
seek() et read() sur l'object fichier peuvent convenir ; si le fichier est "petit", tu peux aussi le lire en une fois et travailler sur les données directement en mémoire. Il y a quelques exemples dans les articles cité au-dessus.
-- DW
* Kevin Denis <kevin@nowhere.invalid> in fr.comp.lang.python:
je cherche à lire différents fichiers binaires dont je connais le
format. Pour les reconnaitre, j'ai besoin de lire quelques octets,
puis de les vérifier, et selon les cas d'en lire plus ou moins
ensuite, etc..
Sur ce thème, il y a pas mal de choses sur StackOverflow :
Je pense a une fonction "walker" qui me lit le fichier octet après
octet et itérer mais n'y a t'il pas un moyen simple de lire des
séquences d'octets à des zones arbitraires du fichier?
seek() et read() sur l'object fichier peuvent convenir ; si le fichier
est "petit", tu peux aussi le lire en une fois et travailler sur les
données directement en mémoire. Il y a quelques exemples dans les
articles cité au-dessus.
je cherche à lire différents fichiers binaires dont je connais le format. Pour les reconnaitre, j'ai besoin de lire quelques octets, puis de les vérifier, et selon les cas d'en lire plus ou moins ensuite, etc..
Sur ce thème, il y a pas mal de choses sur StackOverflow :
Je pense a une fonction "walker" qui me lit le fichier octet après octet et itérer mais n'y a t'il pas un moyen simple de lire des séquences d'octets à des zones arbitraires du fichier?
seek() et read() sur l'object fichier peuvent convenir ; si le fichier est "petit", tu peux aussi le lire en une fois et travailler sur les données directement en mémoire. Il y a quelques exemples dans les articles cité au-dessus.
-- DW
Pierre Maurette
Kevin Denis :
Bonjour,
je cherche à lire différents fichiers binaires dont je connais le format. Pour les reconnaitre, j'ai besoin de lire quelques octets, puis de les vérifier, et selon les cas d'en lire plus ou moins ensuite, etc..
Pour répondre, j'ai en tête un exemple certainement très proche, lecture d'un fichier .iso, identification de son format, et si possible extraction de son contenu. Le tout sur site (1&1).
Je pense a une fonction "walker" qui me lit le fichier octet après octet et itérer mais n'y a t'il pas un moyen simple de lire des séquences d'octets à des zones arbitraires du fichier?
Je ne comprends pas trop le souci. Pour avoir un code plus lisible, vous pouvez commencer par utiliser systématiquement une fonction comme:
Intuitivement, il n'y a pas de surcoût significatif à faire un file.seek() avant un file.read(). Surtout pour des lectures ponctuelles, vous pouvez même négliger os.SEEK_CUR et le remplacer éventuellement par file.tell(), si ça vous convient mieux.
En revanche vous aurez certainement avantage à limiter raisonnablement le nombre des opérations de lecture. Simplement en lisant un morceau, disons une table, et en utilisant ensuite les slices pour l'extraction.
Pensez à binascii.hexlify pour récupérer des valeurs numériques. Un exemple de début de boite à outils:
from binascii import hexlify
""" returns an integer value from a n bytes list in 'little endian' """ def intvallittle(zone): return int(hexlify(zone[::-1]), 16)
""" returns an integer value from a n bytes list in 'big endian' """ def intvalbig(zone): return int(hexlify(zone), 16)
""" returns an integer value from a 2n bytes list in 'both endian' """ def intvalboth(zone): return int(hexlify(zone[len(zone)/2:]), 16)
""" debug - returns a string 'decimal (hexadecimal)' from an integer value """ def dispint(val): return '%d (0x%04X)' % (val, val)
""" debug - returns a string 'hex.hex. ... .hex' from a bytes slice """ def rawdata(zone): return '.'.join(map(hex,map(ord, zone)))
D'un autre coté, c'est quand il s'agira de récupérer de grosses données à partir de gros fichiers qu'il faudra sans doute contourner la lecture directe et mettre en place une lecture séquentielle. Avant la performance, c'est la limitation de la taille des objets qui sera une limitation. Dans le cas d'un hébergement mutualisé, cette limitation sera peut-être non négociable et même difficile à connaitre. La littérature est abondante sur le sujet, avec Google essayer /python/ /file.read/ /chunk/ etc. Un exemple non publiable et écrit avec les pieds (fo est extérieur à la fonction et au minimum mal nommé):
""" create file 'name' filled with dataL bytes read from offset dataB in fo read and write-append is chunked by chunkSZ bytes chunks """ def copyFile(dataB, dataL, chunkSZ, name): if dataL <= chunkSZ: fo.seek(dataB, os.SEEK_SET) open(name, 'wb').write(fo.read(dataL)) else: dataE = dataB + dataL fo.seek(dataB, os.SEEK_SET) open(name, 'wb').write(fo.read(chunkSZ)) if dataL > chunkSZ: f = open(name, 'ab') while 1: dataB += chunkSZ if dataB > dataE: break fo.seek(dataB, os.SEEK_SET) data = fo.read(min(chunkSZ, dataE - dataB)) f.write(data)
-- Pierre Maurette
Kevin Denis :
Bonjour,
je cherche à lire différents fichiers binaires dont je connais le
format.
Pour les reconnaitre, j'ai besoin de lire quelques octets, puis
de les vérifier, et selon les cas d'en lire plus ou moins ensuite,
etc..
Pour répondre, j'ai en tête un exemple certainement très proche,
lecture d'un fichier .iso, identification de son format, et si possible
extraction de son contenu. Le tout sur site (1&1).
Je pense a une fonction "walker" qui me lit le fichier octet après
octet et itérer mais n'y a t'il pas un moyen simple de lire des
séquences d'octets à des zones arbitraires du fichier?
Je ne comprends pas trop le souci. Pour avoir un code plus lisible,
vous pouvez commencer par utiliser systématiquement une fonction comme:
Intuitivement, il n'y a pas de surcoût significatif à faire un
file.seek() avant un file.read(). Surtout pour des lectures
ponctuelles, vous pouvez même négliger os.SEEK_CUR et le remplacer
éventuellement par file.tell(), si ça vous convient mieux.
En revanche vous aurez certainement avantage à limiter raisonnablement
le nombre des opérations de lecture. Simplement en lisant un morceau,
disons une table, et en utilisant ensuite les slices pour l'extraction.
Pensez à binascii.hexlify pour récupérer des valeurs numériques. Un
exemple de début de boite à outils:
from binascii import hexlify
""" returns an integer value from a n bytes list in 'little endian' """
def intvallittle(zone):
return int(hexlify(zone[::-1]), 16)
""" returns an integer value from a n bytes list in 'big endian' """
def intvalbig(zone):
return int(hexlify(zone), 16)
""" returns an integer value from a 2n bytes list in 'both endian' """
def intvalboth(zone):
return int(hexlify(zone[len(zone)/2:]), 16)
""" debug - returns a string 'decimal (hexadecimal)' from an integer
value """
def dispint(val):
return '%d (0x%04X)' % (val, val)
""" debug - returns a string 'hex.hex. ... .hex' from a bytes slice """
def rawdata(zone):
return '.'.join(map(hex,map(ord, zone)))
D'un autre coté, c'est quand il s'agira de récupérer de grosses données
à partir de gros fichiers qu'il faudra sans doute contourner la lecture
directe et mettre en place une lecture séquentielle. Avant la
performance, c'est la limitation de la taille des objets qui sera une
limitation. Dans le cas d'un hébergement mutualisé, cette limitation
sera peut-être non négociable et même difficile à connaitre. La
littérature est abondante sur le sujet, avec Google essayer /python/
/file.read/ /chunk/ etc. Un exemple non publiable et écrit avec les
pieds (fo est extérieur à la fonction et au minimum mal nommé):
""" create file 'name' filled with dataL bytes read from offset dataB
in fo
read and write-append is chunked by chunkSZ bytes chunks
"""
def copyFile(dataB, dataL, chunkSZ, name):
if dataL <= chunkSZ:
fo.seek(dataB, os.SEEK_SET)
open(name, 'wb').write(fo.read(dataL))
else:
dataE = dataB + dataL
fo.seek(dataB, os.SEEK_SET)
open(name, 'wb').write(fo.read(chunkSZ))
if dataL > chunkSZ:
f = open(name, 'ab')
while 1:
dataB += chunkSZ
if dataB > dataE:
break
fo.seek(dataB, os.SEEK_SET)
data = fo.read(min(chunkSZ, dataE - dataB))
f.write(data)
je cherche à lire différents fichiers binaires dont je connais le format. Pour les reconnaitre, j'ai besoin de lire quelques octets, puis de les vérifier, et selon les cas d'en lire plus ou moins ensuite, etc..
Pour répondre, j'ai en tête un exemple certainement très proche, lecture d'un fichier .iso, identification de son format, et si possible extraction de son contenu. Le tout sur site (1&1).
Je pense a une fonction "walker" qui me lit le fichier octet après octet et itérer mais n'y a t'il pas un moyen simple de lire des séquences d'octets à des zones arbitraires du fichier?
Je ne comprends pas trop le souci. Pour avoir un code plus lisible, vous pouvez commencer par utiliser systématiquement une fonction comme:
Intuitivement, il n'y a pas de surcoût significatif à faire un file.seek() avant un file.read(). Surtout pour des lectures ponctuelles, vous pouvez même négliger os.SEEK_CUR et le remplacer éventuellement par file.tell(), si ça vous convient mieux.
En revanche vous aurez certainement avantage à limiter raisonnablement le nombre des opérations de lecture. Simplement en lisant un morceau, disons une table, et en utilisant ensuite les slices pour l'extraction.
Pensez à binascii.hexlify pour récupérer des valeurs numériques. Un exemple de début de boite à outils:
from binascii import hexlify
""" returns an integer value from a n bytes list in 'little endian' """ def intvallittle(zone): return int(hexlify(zone[::-1]), 16)
""" returns an integer value from a n bytes list in 'big endian' """ def intvalbig(zone): return int(hexlify(zone), 16)
""" returns an integer value from a 2n bytes list in 'both endian' """ def intvalboth(zone): return int(hexlify(zone[len(zone)/2:]), 16)
""" debug - returns a string 'decimal (hexadecimal)' from an integer value """ def dispint(val): return '%d (0x%04X)' % (val, val)
""" debug - returns a string 'hex.hex. ... .hex' from a bytes slice """ def rawdata(zone): return '.'.join(map(hex,map(ord, zone)))
D'un autre coté, c'est quand il s'agira de récupérer de grosses données à partir de gros fichiers qu'il faudra sans doute contourner la lecture directe et mettre en place une lecture séquentielle. Avant la performance, c'est la limitation de la taille des objets qui sera une limitation. Dans le cas d'un hébergement mutualisé, cette limitation sera peut-être non négociable et même difficile à connaitre. La littérature est abondante sur le sujet, avec Google essayer /python/ /file.read/ /chunk/ etc. Un exemple non publiable et écrit avec les pieds (fo est extérieur à la fonction et au minimum mal nommé):
""" create file 'name' filled with dataL bytes read from offset dataB in fo read and write-append is chunked by chunkSZ bytes chunks """ def copyFile(dataB, dataL, chunkSZ, name): if dataL <= chunkSZ: fo.seek(dataB, os.SEEK_SET) open(name, 'wb').write(fo.read(dataL)) else: dataE = dataB + dataL fo.seek(dataB, os.SEEK_SET) open(name, 'wb').write(fo.read(chunkSZ)) if dataL > chunkSZ: f = open(name, 'ab') while 1: dataB += chunkSZ if dataB > dataE: break fo.seek(dataB, os.SEEK_SET) data = fo.read(min(chunkSZ, dataE - dataB)) f.write(data)