Python - 使用defaultdict复制文件查找器

时间:2015-09-21 21:17:44

标签: python

通过循环遍历文件夹A-Z所在的顶级目录,我尝试了基于文件内容识别重复文件的不同方法。在文件夹A-Z中,还有一个以当前日期命名的附加文件夹层。最后,在过时的文件夹中,存在数千到数百万(<3百万)个不同格式的文件。

使用下面的脚本,我能够在大约4小时内处理大约800,000个文件。但是,在大约13,000,000个文件的较大数据集上运行它总是在字母上打破#34;我&#34;它包含大约150万个文件。

考虑到数据的大小我正在考虑将内容直接输出到文本文件,然后将其导入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:\Python34\lib\os.py", line 379, in walk
    yield from walk(new_path, topdown, onerror, followlinks)
  File "C:\Python34\lib\os.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 = "\\\\path\\to\\files\\"
directories = [name for name in os.listdir(directory) if os.path.isdir(os.path.join(directory, name))]
outFile = open("\\path\\output.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()))

1 个答案:

答案 0 :(得分:0)

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

我看了你的代码,我意识到错误是由.walk引起的。现在确实这可能是因为处理了太多信息(因此可能外部数据库会有所帮助,尽管添加的操作可能会阻碍您的速度)。但除此之外,.listdir(由.walk调用)在处理大量文件时非常糟糕。希望这是resolved in Python 3.5因为它实现了更好scandir的方式,所以如果你愿意*尝试最新的(我的意思是最新的,那就是发布,什么,{{3 },)可能帮助。

除此之外,您可以尝试跟踪8 days ago?bottlenecks,以便明白这一点。

*您也可以使用当前的python使用pip安装它,但其中的乐趣在哪里?