J'essaie d'écrire un petit script qui imprime la somme de contrôle d'un fichier (en utilisant du code de https://Gist.github.com/Zireael-N/ed36997fd1a967d78cb2 ):
import sys
import os
import hashlib
file = '/Users/Me/Downloads/2017-11-29-raspbian-stretch.img'
with open(file, 'rb') as f:
contents = f.read()
print('SHA256 of file is %s' % hashlib.sha256(contents).hexdigest())
Mais je reçois le message d'erreur suivant:
Traceback (most recent call last):
File "checksum.py", line 8, in <module>
contents = f.read()
OSError: [Errno 22] Invalid argument
Qu'est-ce que je fais mal? J'utilise python 3 sur macOS High Sierra
Il y a ont étéplusieursproblèmes au cours de l'histoire de Python (le plus corrigé dans les versions récentes) lisant plus de 2 à 4 Go à la fois à partir d'un descripteur de fichier (une version non réparable du problème se produit également sur les versions 32 bits de Python, où il leur manque simplement l'espace d'adressage virtuel pour allouer le tampon; pas lié aux E/S, mais vu le plus souvent slurping fichiers de grande taille.) Une solution de contournement disponible pour le hachage consiste à mettre à jour le hachage en morceaux de taille fixe (ce qui est une bonne idée de toute façon, car compter sur RAM étant plus grand que la taille du fichier est une mauvaise idée). L'approche la plus simple consiste à modifier votre code pour:
with open(file, 'rb') as f:
hasher = hashlib.sha256() # Make empty hasher to update piecemeal
while True:
block = f.read(64 * (1 << 20)) # Read 64 MB at a time; big, but not memory busting
if not block: # Reached EOF
break
hasher.update(block) # Update with new block
print('SHA256 of file is %s' % hasher.hexdigest()) # Finalize to compute digest
Si vous en avez envie, vous pouvez "simplifier" la boucle en utilisant la magie à deux arguments iter
et un peu de functools
, en remplaçant l'ensemble de la boucle while
par:
for block in iter(functools.partial(f.read, 64 * (1 << 20)), b''):
hasher.update(block)