You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python脚本文件名循环遍历CPU占用过高,如何优化?

解决大量文件场景下生成文件名的CPU占用过高问题

你的问题很典型:当文件数量达到几千级时,逐个调用os.path.exists()检查文件名会产生大量磁盘IO操作——磁盘本身是慢设备,CPU会频繁等待IO完成,最终导致占用率飙升。咱们来拆解问题,一步步优化:

原代码的核心问题

原代码的逻辑是从number=1开始,逐个生成文件名并检查是否存在:

number = 1
while True:
    fname = "Capture_" + str(number) + ".jpg"
    if not os.path.exists(fname):
        break
    number = number + 1
    DoSomething(fname)

每循环一次就触发一次磁盘查询,5000个文件就要做5000次IO,这是性能瓶颈的根源。

优化思路:批量获取+数字排序

你提到用max(glob.glob('Capture_*.jpg'))会遇到字符串排序的坑(比如Capture_999.jpg会被当成比Capture_1000.jpg大的字符串),这个问题的关键是要从文件名里提取数字值,而不是直接比较字符串。

优化后的代码(基础版)

我们可以一次性获取所有匹配的文件,提取每个文件名中的数字,排序后处理文件并得到下一个编号:

import glob

# 1. 批量获取所有符合格式的文件
matched_files = glob.glob('Capture_*.jpg')

# 2. 提取文件名中的数字,过滤无效文件
valid_entries = []
for file in matched_files:
    try:
        # 拆分文件名:Capture_123.jpg → 提取123
        num_str = file.split('_')[1].split('.')[0]
        num = int(num_str)
        valid_entries.append( (num, file) )
    except (IndexError, ValueError):
        # 忽略命名不符合规则的文件
        continue

# 3. 按数字从小到大排序,保证处理顺序和原逻辑一致
valid_entries.sort()

# 4. 处理所有已存在的文件
for num, fname in valid_entries:
    DoSomething(fname)

# 5. 获取下一个可用编号(如果没有文件则从1开始)
next_number = max( [entry[0] for entry in valid_entries], default=0 ) + 1
new_fname = f"Capture_{next_number}.jpg"

更高效的进阶版:用os.scandir()

如果文件数量特别大(比如几万级),os.scandir()比glob更高效——它直接从操作系统获取目录条目信息,减少了额外的系统调用:

import os

valid_entries = []
with os.scandir('.') as entries:
    for entry in entries:
        # 只处理文件,且符合命名规则
        if entry.is_file() and entry.name.startswith('Capture_') and entry.name.endswith('.jpg'):
            try:
                num = int(entry.name.split('_')[1].split('.')[0])
                valid_entries.append( (num, entry.name) )
            except (IndexError, ValueError):
                continue

# 后续排序、处理、获取编号的逻辑和上面一致
valid_entries.sort()
for num, fname in valid_entries:
    DoSomething(fname)

next_number = max( [entry[0] for entry in valid_entries], default=0 ) + 1
new_fname = f"Capture_{next_number}.jpg"

为什么这样优化?

  1. 减少磁盘IO次数:从原来的几千次IO变成1次(批量获取文件),彻底解决CPU等待IO的问题;
  2. 正确获取最大编号:通过提取数字值比较,避免了字符串排序的陷阱;
  3. 处理逻辑更清晰:把「查找文件」「处理文件」「生成新编号」拆分开,可读性和可维护性更好。

内容的提问来源于stack exchange,提问作者Naveenchandar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:28:40