我正在寻找一种方法来遍历包含100,000个文件的目录。 使用os.listdir
TERRIBLY很慢,因为这个函数首先从整个指定的path中取得path列表。
什么是最快的select?
注:谁downvoted从来没有面对这种情况是肯定的。
这个问题在评论中被称为重复:
将文件夹中的文件列为流,以立即开始处理
…但我发现这个例子是半工半工。 这里是适合我的固定版本:
from ctypes import CDLL, c_int, c_uint8, c_uint16, c_uint32, c_char, c_char_p, Structure, POINTER from ctypes.util import find_library import os class c_dir(Structure): pass class c_dirent(Structure): _fields_ = [ ("d_fileno", c_uint32), ("d_reclen", c_uint16), ("d_type", c_uint8), ("d_namlen", c_uint8), ("d_name", c_char * 4096), # proper way of getting platform MAX filename size? # ("d_name", c_char * (os.pathconf('.', 'PC_NAME_MAX')+1) ) ] c_dirent_p = POINTER(c_dirent) c_dir_p = POINTER(c_dir) c_lib = CDLL(find_library("c")) opendir = c_lib.opendir opendir.argtypes = [c_char_p] opendir.restype = c_dir_p # FIXME Should probably use readdir_r here readdir = c_lib.readdir readdir.argtypes = [c_dir_p] readdir.restype = c_dirent_p closedir = c_lib.closedir closedir.argtypes = [c_dir_p] closedir.restype = c_int def listdir(path): """ A generator to return the names of files in the directory passed in """ dir_p = opendir(".") try: while True: p = readdir(dir_p) if not p: break name = p.contents.d_name if name not in (".", ".."): yield name finally: closedir(dir_p) if __name__ == "__main__": for name in listdir("."): print name
你在做什么目录中的每个文件? 我认为使用os.listdir没有什么选择,但根据你在做什么,你可能能够并行处理文件。 例如,我们可以使用多处理库中的Pool产生更多的Python进程,然后让每个进程遍历一个更小的文件子集。
http://docs.python.org/library/multiprocessing.html
这是一个粗糙的,但我认为它得到了点…
import sys import os from processing import Pool p = Pool(3) def work(subsetOfFiles): for file in subsetOfFiles: with open(file, 'r') as f: #read file, do work return "data" p.map(work, [[#subSetFiles1],[#subSetFiles2],[#subSetFiles3]])
总体思路是从os.listdir中获取文件列表,而不是逐个超过100,000个文件,我们将100,000个文件分成20个5000个文件列表,每个进程处理5000个文件。 这种方法的好处之一是它将受益于当前多核系统的趋势。