“OSError: Argumento no válido” cuando se lee () un archivo enorme

Estoy tratando de escribir un pequeño script que imprima la sum de comprobación de un archivo (usando algún código 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()) 

Pero estoy recibiendo el siguiente mensaje de error:

 Traceback (most recent call last): File "checksum.py", line 8, in  contents = f.read() OSError: [Errno 22] Invalid argument 

¿Qué estoy haciendo mal? Estoy usando python 3 en macOS High Sierra

Ha habido varios problemas a lo largo de la historia de Python (la mayoría se ha corregido en versiones recientes) al leer más de 2 a 4 GB a la vez desde un identificador de archivo (una versión no solucionable del problema también se produce en las comstackciones de Python de 32 bits, donde simplemente no existen el espacio de direcciones virtuales para asignar el búfer; no relacionado con E / S, pero visto con mayor frecuencia en los archivos de gran tamaño). Una solución alternativa disponible para el hash es actualizar el hash en trozos de tamaño fijo (lo cual es una buena idea de todos modos, ya que contar con RAM es mayor que el tamaño del archivo es una mala idea). El enfoque más directo es cambiar su código a:

 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 te sientes lujoso, puedes "simplificar" el bucle usando el iter dos functools y algunas functools mágicas, reemplazando todo el bucle while con:

 for block in iter(functools.partial(f.read, 64 * (1 << 20)), b''): hasher.update(block)