当目录中的filecount大于2.500.000时,使用NTFS和Windows 7迭代目录中所有文件的最快方法是什么? 所有文件在顶级目录下都是平的。
目前我使用
for root, subFolders, files in os.walk(rootdir):
for file in files:
f = os.path.join(root,file)
with open(f) as cf:
[...]
但它非常慢。该过程已经运行了大约一个小时,仍然没有处理单个文件,但仍然以每秒大约2kB的内存使用量增长。
答案 0 :(得分:5)
默认情况下os.walk
自下而上遍历目录树。如果你有一个有许多叶子的深树,我猜测这可能会留给性能惩罚 - 或者至少增加“statup”时间,因为walk
必须读取大量数据在处理第一个文件之前。
所有这些都是推测性的,你是否试图强制进行自上而下的探索:
for root, subFolders, files in os.walk(rootdir, topdown=True):
...
修改强>
由于文件似乎位于一个平面目录中,因此返回迭代器可能glob.iglob
可能会提高性能(而os.walk
,os.listdir
或{{1}等其他方法首先构建所有文件的列表。你可以尝试这样的事情:
glob.glob
答案 1 :(得分:1)
我发现 os.scandir
(从 3.5 开始在 python 标准库中)似乎在 Windows 中也能做到这一点!
(仅在 Windows 上测试过……不确定其他操作系统)!
考虑以下示例:
“从包含数百万个文件的文件夹中检索 100 个路径”
os.scandir
可在几分之一秒内实现这一目标
import os
from itertools import islice
from pathlib import Path
path = Path("path to a folder with a lot of files")
paths = [i.path for i in islice(os.scandir(path), 100))]
所有其他经过测试的选项 (iterdir, glob, iglob
) 以某种方式花费了大量时间,即使它们应该返回迭代器...
paths = list(islice(path.iterdir(), 100))
paths = list(islice(path.rglob(""), 100))
import glob
paths = list(islice(glob.iglob(str(path / "*.*")), 100))
答案 2 :(得分:-1)
我使用了这样的东西:
from os import scandir
from os.path import isfile, join, exists
import os
def get_files(path):
if exists(path):
for file in scandir(path):
full_path = join(path, file.name)
if isfile(full_path):
yield full_path
else:
print('Path doesn\'t exist')
def get_subdirs(path):
if exists(path):
for subdir in scandir(path):
full_path = join(path, subdir.name)
if not isfile(full_path):
yield full_path
else:
print('Path doesn\'t exist')
def walk_dir(directory):
yield from get_files(directory)
for subdir in get_subdirs(directory):
yield from walk_dir(subdir)
walk_dir
方法返回一个生成器对象,该生成器对象可用于遍历文件系统。在递归过程的任何步骤,都不会创建目录列表,因此内存永远不会保存任何子目录中的所有文件的列表。