给定一个包含大量小文件(> 1 mio)的目录,记住哪些文件已经被处理(用于数据库导入)是一种快速的方法。
我尝试的第一个解决scheme是一个bash脚本:
#find all gz files for f in $(find $rawdatapath -name '*.gz'); do filename=`basename $f` #check whether the filename is already contained in the process list onlist=`grep $filename $processed_files` if [[ -z $onlist ]] then echo "processing, new: $filename" #unzip file and import into mongodb #write filename into processed list echo $filename #>> $processed_files fi done
对于一个较小的样本(160k文件),这运行了大约8分钟(没有任何处理)
接下来我尝试了一个python脚本:
import os path = "/home/b2blogin/webapps/mongodb/rawdata/segment_slideproof_testing" processed_files_file = os.path.join(path,"processed_files.txt") processed_files = [line.strip() for line in open(processed_files_file)] with open(processed_files_file, "a") as pff: for root, dirs, files in os.walk(path): for file in files: if file.endswith(".gz"): if file not in processed_files: pff.write("%s\n" % file)
这运行不到2分钟。
有没有一个明显更快的方式,我俯瞰?
其他解决scheme
只要使用一套:
import os path = "/home/b2blogin/webapps/mongodb/rawdata/segment_slideproof_testing" processed_files_file = os.path.join(path,"processed_files.txt") processed_files = set(line.strip() for line in open(processed_files_file)) with open(processed_files_file, "a") as pff: for root, dirs, files in os.walk(path): for file in files: if file.endswith(".gz"): if file not in processed_files: pff.write("%s\n" % file)
使用标准命令行工具的替代方法:
只需将包含所有文件列表的文件与包含已处理文件列表的文件进行比较即可。
易于尝试,而且应该相当快。
如果您在列表中包含完整的时间戳,则可以通过这种方式获取“已更改”的文件。
如果文件在处理后没有被修改,一个选项是记住最新的处理文件 ,然后使用find
的-newer
选项来检索尚未处理的文件。
find $rawdatapath -name '*.gz' -newer $(<latest_file) -exec process.sh {} \;
process.sh看起来像
#!/bin/env bash echo "processing, new: $1" #unzip file and import into mongodb echo $1 > latest_file
这是未经测试的。 在考虑实施这一战略之前,应该注意不必要的副作用。
如果一个hacky / quick'n'dirty解决方案是可以接受的, 一个时髦的选择是编码状态(处理或不处理)的文件权限 ,例如在组读取权限位。 假设你的umask
是022
,所以任何新创建的文件都有权限644
,在处理文件后将权限改为600
,并使用find
的-perm
选项来检索尚未处理的文件。
find $rawdatapath -name '*.gz' -perm 644 -exec process.sh {} \;
process.sh看起来像
#!/bin/env bash echo "processing, new: $1" #unzip file and import into mongodb chmod 600 $1
这再次没有经过测试。 在考虑实施这一战略之前,应该注意不必要的副作用。