迭代文件夹中的大量文件

时间:2013-06-10 09:11:58

标签: python windows

当目录中的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的内存使用量增长。

3 个答案:

答案 0 :(得分:5)

默认情况下os.walk自下而上遍历目录树。如果你有一个有许多叶子的深树,我猜测这可能会留给性能惩罚 - 或者至少增加“statup”时间,因为walk必须读取大量数据在处理第一个文件之前。

所有这些都是推测性的,你是否试图强制进行自上而下的探索:

for root, subFolders, files in os.walk(rootdir, topdown=True):
    ...

修改

由于文件似乎位于一个平面目录中,因此返回迭代器可能glob.iglob可能会提高性能(而os.walkos.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方法返回一个生成器对象,该生成器对象可用于遍历文件系统。在递归过程的任何步骤,都不会创建目录列表,因此内存永远不会保存任何子目录中的所有文件的列表。