python - 如何在大型文件系统中查找重复文件同时避免 MemoryError

标签 python hash duplicates out-of-memory

我试图避免在我的 mp3 收藏中重复(非常大)。我想通过检查文件内容来检查重复项,而不是查找相同的文件名。我已经编写了下面的代码来执行此操作,但它会在大约一分钟后抛出 MemoryError。关于如何让它工作的任何建议?

import os
import hashlib

walk = os.walk('H:\MUSIC NEXT GEN')

mySet = set()
dupe  = []

hasher = hashlib.md5()

for dirpath, subdirs, files in walk:
    for f in files:
        fileName =  os.path.join(dirpath, f)
        with open(fileName, 'rb') as mp3:
            buf = mp3.read()
            hasher.update(buf)
            hashKey = hasher.hexdigest()
            print hashKey
            if hashKey in mySet:
                dupe.append(fileName)
            else:
                mySet.add(hashKey)


print 'Dupes: ' + str(dupe)

最佳答案

您可能有一个巨大的文件,无法像您尝试使用 mp3.read() 那样立即读取。改为阅读较小的部分。将它放入一个漂亮的小函数中也有助于保持主程序的清洁。这是我自己使用了一段时间的功能(现在只是稍微完善了它),用于可能与您的工具类似的工具:

import hashlib

def filehash(filename):
    with open(filename, mode='rb') as file:
        hasher = hashlib.md5()
        while True:
            buffer = file.read(1 << 20)
            if not buffer:
                return hasher.hexdigest()
            hasher.update(buffer)

更新:A readinto版本:

buffer = bytearray(1 << 20)
def filehash(filename):
    with open(filename, mode='rb') as file:
        hasher = hashlib.md5()
        while True:
            n = file.readinto(buffer)
            if not n:
                return hasher.hexdigest()
            hasher.update(buffer if n == len(buffer) else buffer[:n])

对于已缓存在内存中的 1GB 文件并进行十次尝试,这平均需要 5.35 秒。 read 版本平均耗时 6.07 秒。在这两个版本中,Python 进程在运行期间占用了大约 10MB 的 RAM。

我可能会坚持使用 read 版本,因为我更喜欢它的简单性,而且在我的实际用例中,数据还没有缓存在 RAM 中,我使用 sha256(所以整体时间显着增加,使 readinto 的小优势变得更加无关紧要)。

关于python - 如何在大型文件系统中查找重复文件同时避免 MemoryError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30064086/

相关文章:

python 2.6,pygame,乒乓球不会正确地在 y 坐标上移动

python - Pandas 错误 : "IndexError: iloc cannot enlarge its target object"

python - 在 Python 中从非常大的文本文件中删除重复项的更快方法?

mysql - 仅在 MySQL 中插入一次或更新(如果存在)- Facebook 应用程序

python - 如何匹配两个 numpy 数组中包含的值对

python - 从不同的类扩展 Python 类的功能

.net - 将密码存储在 SQL Server 数据库中。 .Net 功能够用吗?

ruby-on-rails - JSON 字符串到 rails 哈希

javascript - 从 DOM 元素中提取属性

batch-file - 使用批处理文件删除重复的文本行