我有一个备份硬盘驱动器,我知道有重复的文件分散在我周围,我认为这是一个有趣的项目编写一个小的python脚本来找到它们并删除它们.我编写以下代码只是为了遍历驱动器并计算每个文件的md5总和,并将其与我将称之为"第一次遇到"列表的内容进行比较.如果md5总和尚不存在,则将其添加到列表中.如果总和已存在,则删除当前文件.
import sys
import os
import hashlib
def checkFile(fileHashMap, file):
fReader = open(file)
fileData = fReader.read();
fReader.close()
fileHash = hashlib.md5(fileData).hexdigest()
del fileData
if fileHash in fileHashMap:
### Duplicate file.
fileHashMap[fileHash].append(file)
return True
else:
fileHashMap[fileHash] = [file]
return False
def main(argv):
fileHashMap = {}
fileCount = 0
for curDir, subDirs, files in os.walk(argv[1]):
print(curDir)
for file in files:
fileCount += 1
print("------------: " + str(fileCount))
print(curDir + file)
checkFile(fileHashMap, curDir + file)
if __name__ == "__main__":
main(sys.argv)
Run Code Online (Sandbox Code Playgroud)
该脚本处理大约10Gb的文件,然后在'fileData = fReader.read()'行上抛出MemoryError.我认为,因为我在关闭fReader并在计算md5总和之后将fileData标记为删除,所以我不会遇到这个问题.如何在不遇到此内存错误的情况下计算md5总和?
编辑:我被要求删除字典并查看内存使用情况,以查看hashlib中是否存在泄漏.这是我运行的代码.
import sys
import os
import hashlib
def checkFile(file):
fReader = open(file)
fileData = fReader.read();
fReader.close()
fileHash = hashlib.md5(fileData).hexdigest()
del fileData
def main(argv):
for curDir, subDirs, files in os.walk(argv[1]):
print(curDir)
for file in files:
print("------: " + str(curDir + file))
checkFile(curDir + file)
if __name__ == "__main__":
main(sys.argv)
Run Code Online (Sandbox Code Playgroud)
我仍然得到内存崩溃.
您的问题在于读取整个文件,它们太大了,您的系统无法将其全部加载到内存中,因此它会抛出错误。
\n\n正如你在 Python 官方文档中看到的,它MemoryError是:
\n\n\n当操作耗尽内存但情况仍然可以挽救(通过删除某些对象)时引发。关联的值是一个字符串,指示哪种(内部)操作耗尽了内存。\n 请注意,由于底层内存管理架构\n(C\xe2\x80\x99s malloc() 函数),解释器可能并不总是能够从这种情况中完全恢复;尽管如此,它还是会引发异常,以便在程序失控的情况下打印堆栈回溯。
\n
为了您的目的,您可以使用hashlib.md5()
在这种情况下,您必须顺序读取 4096 字节的块并将它们提供给 Md5 函数:
\n\ndef md5(fname):\n hash = hashlib.md5()\n with open(fname) as f:\n for chunk in iter(lambda: f.read(4096), ""):\n hash.update(chunk)\n return hash.hexdigest()\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1477 次 |
| 最近记录: |