“OSError:[Errno 22]在读取大型fi时参数无效”

2024-04-25 18:19:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图编写一个小脚本来打印文件的校验和(使用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())

但我收到了以下错误消息:

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

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


Tags: 代码httpsimportgithubcomreadcontents校验
1条回答
网友
1楼 · 发布于 2024-04-25 18:19:04

在Python(最新版本中已修复)的历史中有have beenseveralissues一次从文件句柄中读取超过2-4gb的数据(问题的不可修复版本也发生在32位的Python构建上,在那里它们只是缺少分配缓冲区的虚拟地址空间;与I/O无关,但最常见的是狼吞虎咽的大文件)。散列的一个解决方法是更新固定大小的块中的散列(这是一个好主意,因为指望RAM大于文件大小是一个坏主意)。最直接的方法是将代码更改为:

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

如果您觉得很有趣,可以使用两个argiter和一些functools魔术来“简化”循环,将整个while循环替换为:

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

相关问题 更多 >