当目录中的文件数大于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:
[...]
Run Code Online (Sandbox Code Playgroud)
但它非常慢.该过程已运行大约一个小时,仍然没有处理单个文件,但仍然以每秒大约2kB的内存使用量增长.
rap*_*ael 10
我发现 os.scandir(从 3.5 开始在 python 标准库中)似乎在 Windows 中也能实现这一点!(正如评论中所指出的,它在 MacOS 上同样出色)!
考虑以下示例:
“从包含数百万个文件的文件夹中检索 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))]
Run Code Online (Sandbox Code Playgroud)
所有其他经过测试的选项(iterdir, glob, iglob)都以某种方式花费了荒谬的时间,即使它们应该返回迭代器......
paths = list(islice(path.iterdir(), 100))
Run Code Online (Sandbox Code Playgroud)
paths = list(islice(path.rglob(""), 100))
Run Code Online (Sandbox Code Playgroud)
import glob
paths = list(islice(glob.iglob(str(path / "*.*")), 100))
Run Code Online (Sandbox Code Playgroud)
默认情况下,从下到上os.walk遍历目录树.如果你有一个有许多叶子的深树,我想这可能会留给性能惩罚 - 或者至少增加"statup"时间,因为walk在处理第一个文件之前必须读取大量数据.
所有这些都是推测性的,你试图强制进行自上而下的探索:
for root, subFolders, files in os.walk(rootdir, topdown=True):
...
Run Code Online (Sandbox Code Playgroud)
编辑:
由于文件似乎位于一个平面目录中,因此可能glob.iglob通过返回迭代器(而其他方法os.walk,os.listdir或glob.glob首先构建所有文件的列表)来提高性能.你可以尝试这样的事情:
import glob
# ...
for infile in glob.iglob( os.path.join(rootdir, '*.*') ):
# ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3927 次 |
| 最近记录: |