【发布时间】:2016-11-04 08:24:28
【问题描述】:
这个问题已经在这个网站上被问过并回答了很多次,但由于一些模糊的原因,没有人想出一个相对简单(在我看来)、更简洁、可能更优雅的解决方案。也许是因为解决方案实际上很糟糕,但这就是我想要弄清楚的,如果它很糟糕,那么我想知道如何以及为什么。 最受欢迎的答案之一是:
def md5(fname):
hash_md5 = hashlib.md5()
with open(fname, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
这是可以理解的——我们不想将整个文件加载到内存中,所以我们在迭代器和 lambda 函数的帮助下分块读取它。很好很简单。 但大概我们可以通过如下定义 md5sum 函数以更简单的方式做到这一点:
def md5sum(fname):
md5 = hashlib.md5()
with open(fname, 'rb') as f:
for chunk in f:
md5.update(chunk)
return md5.hexdigest()
方便地,对打开的文件句柄进行迭代会为我们提供一系列行,因此我们可以使用 open(fname, 'rb') 中的“b”前缀来迭代字节对象。这样做有什么问题?
【问题讨论】:
-
这可能与您正在处理的文件类型有关,特别是它实际上是 ascii 文件还是二进制文件。原始版本对块大小提供了更多控制,而您的版本则受制于此处和那里的换行符。此外,为了处理大文件,我不仅一次使用 4K 数据,而且至少使用 100K,只是为了确保“分块”中没有显着的开销。我曾经有过使用 zip 模块的经验,今天 100K 不算什么。
-
@Dr.V 我明白了,我几乎同意你所说的一切,但据我所知,它适用于各种文件。
-
@weeCoder 尝试创建一个 not 包含
\x0a字节的大文件,然后查看...for chunk in f降级为chunk = f.read()读取整个文件进入记忆。 -
@PM2Ring 哦,谢谢,这几乎回答了我的问题。如果您认为它对其他人有任何用处,您应该将其发布为答案。
标签: python