Python中如何高效读取一个文件夹下的百万个文件?

之前把爬虫爬取的源文件都存在了一个文件夹,有一百多万个,现在要读取,直接用 os.walk(path) 这种方式,几个小时了还卡在这一步,有没有其他的方式可以快速的读取
Python中如何高效读取一个文件夹下的百万个文件?

15 回复

ls /xxx >list


核心思路:分批次处理 + 惰性迭代,避免一次性加载所有文件路径到内存。

直接上代码,用 os.scandir()pathlib 的惰性迭代器,配合生成器分批处理:

import os
from pathlib import Path

def process_million_files(folder_path, batch_size=1000):
    """
    高效处理百万量级文件的生成器函数。
    每次yield一个批次的文件路径列表。
    """
    # 方法1: 使用 os.scandir() - 更底层,性能通常最好
    with os.scandir(folder_path) as entries:
        batch = []
        for entry in entries:
            if entry.is_file():  # 只处理文件,忽略目录
                batch.append(entry.path)
                if len(batch) >= batch_size:
                    yield batch
                    batch = []
        if batch:  # 处理最后一批
            yield batch

    # 方法2: 使用 pathlib (代码更简洁,性能稍逊但可接受)
    # folder = Path(folder_path)
    # batch = []
    # for file_path in folder.iterdir():
    #     if file_path.is_file():
    #         batch.append(str(file_path))
    #         if len(batch) >= batch_size:
    #             yield batch
    #             batch = []
    # if batch:
    #     yield batch

# 使用示例
folder = "/path/to/your/million/files"
for file_batch in process_million_files(folder, batch_size=5000):
    # 在这里处理每个批次的文件
    for file_path in file_batch:
        # 执行你的文件处理逻辑,例如:
        # with open(file_path, 'r') as f:
        #     content = f.read()
        #     # 处理内容...
        pass  # 替换为实际处理代码
    # 处理完一批后,内存会被释放,接着处理下一批

关键点:

  • os.scandir() 在底层系统调用层面就比 os.listdir() 高效,因为它能在一次系统调用中获取文件类型信息。
  • 使用生成器 (yield) 实现惰性加载,内存中只保持一个批次的数据。
  • 通过 batch_size 控制内存占用,根据你的内存情况调整(通常1000-10000)。
  • 如果只需要处理特定类型文件,可以在 if entry.is_file() 后添加扩展名过滤。

一句话建议:用 os.scandir() 加生成器分批处理,别一次性全读进内存。

<br>import subprocess<br>cat = subprocess.Popen(["ll",], stdout=subprocess.PIPE)<br> for line in cat.stdout:<br> print line<br>

一看楼上就是没有遇到过几百万文件在一个目录的情况,之前遇到过(因为 crontab 用了 wget 导致的),用 ls 命令已经不好使了,这个时候只能通过文件名字的规律来处理了,比如文件名是五位数字,可以试试 ls 11* 这种方式缩小每次读取的文件数量

$ time ls -U | wc -l
5973243

real 0m2.330s
user 0m1.743s
sys 0m0.790s

不用-U 要 24 秒多

正解,U 参数!我用 ls -U 删了两千万文件……

100 万 , 真刺激

find > a 生成索引,在使用 python 去处理一个几百万行的文本即可。

那如果是在 windows 下呢

win 下就不知道了,没经历过

想起某童鞋经历过的 inode 用完的情况。。。。

学习了

这样会多出一项

回到顶部