通过循环遍历文件夹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()))
答案 0 :(得分:0)
免责声明:我不知道这是否是一个解决方案。
我看了你的代码,我意识到错误是由.walk
引起的。现在确实这可能是因为处理了太多信息(因此可能外部数据库会有所帮助,尽管添加的操作可能会阻碍您的速度)。但除此之外,.listdir
(由.walk
调用)在处理大量文件时非常糟糕。希望这是resolved in Python 3.5因为它实现了更好scandir的方式,所以如果你愿意*尝试最新的(我的意思是最新的,那就是发布,什么,{{3 },)可能帮助。
除此之外,您可以尝试跟踪8 days ago?和bottlenecks,以便明白这一点。
*您也可以使用当前的python使用pip安装它,但其中的乐趣在哪里?