我需要扫描文件系统以获取文件列表,并记录那些不存在的文件。目前我有一个输入文件,其中包含需要调查的1300万个文件的列表。此脚本需要从远程位置运行,因为我没有访问/无法直接在存储服务器上运行脚本。
我目前的做法有效,但相对较慢。我仍然是Python的新手,所以我正在寻找加快速度的技巧。
import sys,os
from pz import padZero #prepends 0's to string until desired length
output = open('./out.txt', 'w')
input = open('./in.txt', 'r')
rootPath = '\\\\server\share\' #UNC path to storage
for ifid in input:
ifid = padZero(str(ifid)[:-1], 8) #extracts/formats fileName
dir = padZero(str(ifid)[:-3], 5) #exracts/formats the directory containing the file
fPath = rootPath + '\\' + dir + '\\' + ifid + '.tif'
try:
size = os.path.getsize(fPath) #don't actually need size, better approach?
except:
output.write(ifid+'\n')
感谢。
答案 0 :(得分:1)
dirs = collections.defaultdict(set)
for file_path in input:
file_path = file_path.rjust(8, "0")
dir, name = file_path[:-3], file_path
dirs[dir].add(name)
for dir, files in dirs.iteritems():
for missing_file in files - set(glob.glob("*.tif")):
print missing_file
首先将输入文件读入目录字典:filename。然后,对于每个目录,列出服务器上该目录中的所有TIFF文件,并(set)从您应该拥有的文件名集合中减去该文件。打印剩下的任何内容。
编辑:修正了愚蠢的事情。我写这篇文章的时候太晚了!
答案 1 :(得分:0)
您将受到I / O限制,特别是在网络上,因此您对脚本所做的任何更改都将导致极低的加速,但不是我的头脑:
import os
input, output = open("in.txt"), open("out.txt", "w")
root = r'\\server\share'
for fid in input:
fid = fid.strip().rjust(8, "0")
dir = fid[:-3] # no need to re-pad
path = os.path.join(root, dir, fid + ".tif")
if not os.path.isfile(path):
output.write(fid + "\n")
我真的不希望它更快,但它可以说更容易阅读。
其他方法可能更快。例如,如果您希望触摸大多数文件,您可以从服务器中提取一个完整的递归目录列表,将其转换为Python set()
,并检查其中的成员资格而不是点击服务器小要求。我将把代码留作练习......
答案 2 :(得分:0)
padZero和字符串连接看起来像是需要花费很多时间。
你想要它做的就是把所有时间都花在阅读目录上,其他几乎没有。
你必须在python中这样做吗?我在C和C ++中做过类似的事情。 Java应该也不错。
答案 3 :(得分:0)
我可能会使用shell命令在一次命中中获取所有目录和子目录中的文件的完整列表。希望这将最大限度地减少您需要向服务器发出的请求数量。
您可以通过以下操作获取远程服务器文件的列表:
mount
共享驱动器为/shared/directory/
,然后执行ls -R /shared/directory > ~/remote_file_list.txt
Map Network Drive
将驱动器号X:
装入共享驱动器,然后执行dir /S X:/shared_directory > C:/remote_file_list.txt
使用相同的方法创建本地文件夹内容的列表local_file_list.txt
。然后,python脚本将缩减为文本处理练习。
注意:我确实必须在工作中这样做。