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

如何规避Python打开文件数量限制以批量发送目录文件?

解决Python打开过多文件报错[Errno 24] Too many open files的方案

问题背景

我需要将用户目录下的所有文件内容通过请求发送,但无法修改接收服务,因此不能将文件压缩后发送,必须发送全部文件。文件总大小有限制,但文件数量无限制。然而当尝试打开过多文件时,Python会报错:[Errno 24] Too many open files。我的当前代码如下:

files_to_send = [] 
files_to_close = [] 
for file_path in all_files: 
    file_obj = open(file_path, "rb") 
    files_to_send.append(("files", (file_path, file_obj))) 
    files_to_close.append(file_obj) 
requests.post(url, files=files_to_send) 
for file_to_close in files_to_close: 
    file_to_close.close() 

可行的解决办法

1. 分批次发送文件(优先推荐)

这是最通用、最稳妥的方案——既然一次性打开所有文件会触发限制,那咱们就把文件分成小批量处理,每批只打开有限数量的文件,发送完成后立刻关闭,再处理下一批。这样能严格控制同时打开的文件数,完全在代码层面解决问题,不需要依赖系统设置。

示例代码如下:

import requests

# 可根据系统默认限制调整批次大小,比如默认ulimit是1024,设500留足余量
BATCH_SIZE = 500

all_files = [...]  # 你的所有文件路径列表
target_url = "你的接收服务URL"

# 按批次遍历文件列表
for batch_start in range(0, len(all_files), BATCH_SIZE):
    batch_files = all_files[batch_start:batch_start + BATCH_SIZE]
    files_to_send = []
    open_files = []
    
    try:
        # 打开当前批次的文件并准备请求参数
        for file_path in batch_files:
            f = open(file_path, "rb")
            files_to_send.append(("files", (file_path, f)))
            open_files.append(f)
        
        # 发送请求
        response = requests.post(target_url, files=files_to_send)
        response.raise_for_status()  # 可选:检查请求是否成功
        print(f"批次{batch_start//BATCH_SIZE +1}发送成功")
    except Exception as e:
        print(f"批次{batch_start//BATCH_SIZE +1}处理失败: {str(e)}")
    finally:
        # 无论请求成功失败,都确保关闭所有打开的文件
        for f in open_files:
            try:
                f.close()
            except Exception:
                # 忽略关闭时的小错误,避免影响后续流程
                pass

2. 临时调整系统文件描述符限制(仅限Unix-like系统)

如果你的运行环境是Linux/macOS,且有足够权限,可以临时提高当前进程的文件描述符上限,让Python能同时打开更多文件。不过这个方法有局限性:Windows系统不支持,且普通用户可能无法修改硬限制,文件数量极多时仍不适用。

示例代码:

import resource

# 获取当前的文件描述符限制(软限制/硬限制)
soft_limit, hard_limit = resource.getrlimit(resource.RLIMIT_NOFILE)
# 设置新的软限制(不能超过硬限制,这里设为4096,可根据需求调整)
new_soft_limit = min(4096, hard_limit)
resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft_limit, hard_limit))

# 之后再执行你原来的发送代码

3. 流式上传(需接收端支持)

如果接收服务支持流式的multipart/form-data上传,你可以用生成器逐个读取文件内容,不需要一次性打开所有文件。不过这个方法需要你手动构造请求体,实现起来相对复杂,且前提是接收端能兼容这种上传方式(你提到不能修改接收服务,所以需要确认它支持)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:56:22