使用defaultdict重复文件查找器

我正在尝试使用不同的方法来根据文件内容识别重复文件,方法是循环访问文件夹AZ所在的顶级目录。 在文件夹AZ中,有一个额外的文件夹层以当前日期命名。 最后,在标有日期的文件夹中,有各种格式的数千到数百万(<300万)个文件。

使用下面的脚本,我能够在大约4个小时内处理大约800,000个文件。 然而,在一个大约1300万个文件的大型数据集上运行它时,它总是会破坏包含大约150万个文件的字母“I”。

鉴于我正在处理的数据大小,我正在考虑将内容直接输出到文本文件,然后将其导入到MySQL或类似的文件中以供进一步处理。 请让我知道,如果我正走向正确的轨道,或者如果您觉得下面的脚本的修改版本应该能够处理1300万个文件。

问题 - 如何修改下面的脚本来处理1300多万个文件?

错误追溯:

Traceback (most recent call last):
  File "C:/Users/"user"/PycharmProjects/untitled/dups.py", line 28, in <module>
    for subdir, dirs, files in os.walk(path):
  File "C:Python34libos.py", line 379, in walk
    yield from walk(new_path, topdown, onerror, followlinks)
  File "C:Python34libos.py", line 372, in walk
    nondirs.append(name)
MemoryError

我的代码:

import hashlib
import os
import datetime
from collections import defaultdict


def hash(filepath):
    hash = hashlib.md5()
    blockSize = 65536
    with open(filepath, 'rb') as fpath:
        block = fpath.read(blockSize)
        while len(block) > 0:
            hash.update(block)
            block = fpath.read(blockSize)
    return hash.hexdigest()


directory = "\pathtofiles"
directories = [name for name in os.listdir(directory) if os.path.isdir(os.path.join(directory, name))]
outFile = open("pathoutput.txt", "w", encoding='utf8')

for folder in directories:
    sizeList = defaultdict(list)
    path = directory + folder
    print("Start time: " + str(datetime.datetime.now()))
    print("Working on folder: " + folder)
    # Walk through one level of directories
    for subdir, dirs, files in os.walk(path):
        for file in files:
            filePath = os.path.join(subdir, file)
            sizeList[os.stat(filePath).st_size].append(filePath)
    print("Hashing " + str(len(sizeList)) + " Files")
    ## Hash remaining files
    fileList = defaultdict(list)
    for fileSize in sizeList.values():
        if len(fileSize) > 1:
            for dupSize in fileSize:
                fileList[hash(dupSize)].append(dupSize)
    ## Write remaining hashed files to file
    print("Writing Output")
    for fileHash in fileList.values():
        if len(fileHash) > 1:
            for hashOut in fileHash:
                outFile.write(hashOut + " ~ " + str(os.stat(hashOut).st_size) + 'n')
            outFile.write('n')
outFile.close()
print("End time: " + str(datetime.datetime.now()))

免责声明:我不知道这是否是一种解决方案。

我看了你的代码,然后我意识到错误是由.walk引起的。 现在的确,这可能是因为太多的信息被处理了(所以也许外部数据库会有所帮助,尽管增加的操作可能会阻碍你的速度)。 但.listdir ,处理大量文件时, .listdir (由.walk调用)真的很糟糕。 希望这可以在Python 3.5中解决,因为它实现了更好的scandir,所以如果你愿意*尝试最新的(我的意思是最新的,它是8天前发布的),这可能会有所帮助。

除此之外,您可以尝试追踪瓶颈,并收集垃圾,以便弄清楚。

*你也可以使用你的当前Python来安装它,但是它的乐趣在哪里?

链接地址: http://www.djcxy.com/p/69955.html

上一篇: Duplicate File Finder using defaultdict

下一篇: List of dictionaries from numpy array without for loop