读取()或读取大型文件时出现“OSError:[Errno 22]无效参数”

我正在尝试编写一个小脚本来打印文件的校验和(使用来自https://gist.github.com/Zireael-N/ed36997fd1a967d78cb2):

导入系统
导入操作系统
导入hashlib
文件=’/Users/Me/Downloads/2017-11-29-raspbian-stretch.img’
打开(文件“rb”)作为f:
contents=f.read()
打印(’文件的SHA256是%s’%hashlib.SHA256(contents.hexdigest())

但我收到以下错误消息:

回溯(最近一次呼叫最后一次):
文件“checksum.py”,第8行,在<模块>
contents=f.read()
OSError:[Errno 22]参数无效

我做错了什么?我在macOS High Sierra上使用python 3

Python(最新版本中的大多数已修复)从文件句柄一次读取超过2-4GB的数据的历史上有几个问题(这个问题的一个不可压缩版本也发生在32位的Python构建上,它们只是缺少分配缓冲区的虚拟地址空间;与I/O无关,但最常见的情况是对大文件进行slurp处理)。散列的一个解决方法是在固定大小的块中更新散列(无论如何,这是个好主意,因为指望RAM大于文件大小是个糟糕的主意)。最简单的方法是将代码更改为:

打开(文件’rb’)作为f时的

:
hasher=hashlib.sha256()#生成空hasher以逐段更新
尽管如此:
block=f.read(64*(1<<20))#一次读取64 MB;大,但不破坏内存
如果未阻塞:#达到EOF
打破
hasher.update(块)#用新块更新
打印('SHA256文件为%s'%hasher.hexdigest())#最终确定为计算摘要

如果您喜欢,可以使用两个argiter和一些functoolsmagic“简化”循环,将整个while循环替换为:

国际热核实验堆(iter)中的模块(functools.partial(f.read,64*(1<<20)),b”:
hasher.update(块)

或者在Python 3.8+上,使用walrus运算符,:=更简单,无需导入或无法读取代码:

while block:=f.read(64*(1<<20)):#赋值和测试结果有条件!
hasher.update(块)

发表评论