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

时间:2018-01-05 23:39:46

标签: python python-3.x macos file-io

我正在尝试编写一个打印文件校验和的小脚本(使用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上使用python 3

2 个答案:

答案 0 :(得分:9)

对于Python的历史记录have been several issues(最近版本中最常修复)从文件句柄一次读取超过2-4 GB(不可修复的版本)问题也发生在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

如果你感觉很花哨,你可以简化&#34;使用两个arg iter和一些functools魔法的循环,用以下内容替换整个while循环:

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

答案 1 :(得分:0)

哇,这可能要简单得多。只需逐行读取文件:

opt[Color]