【发布时间】:2020-11-02 08:30:04
【问题描述】:
当我使用requests 模块通过一个请求上传至少400 个文件时,我在macOS 系统上收到Too many open files 错误。
我试过ulimit -n 20000。
也检查了:
-
sysctl kern.maxfiles得到98304 -
sysctl kern.maxfilesperproc得到49152
但是,它不起作用。
这是我的代码:
import os
import requests
url = 'http://127.0.0.1:8000/api/upload'
file_path = '/Users/BonJu/Projects/downloads'
file_list = os.listdir(file_path)
files = []
for file in file_list:
try:
source = open(os.path.join(file_path, file), 'rb')
files.append(('file', source))
except Exception as e:
print('File: %s, Error: %s' % (file, e.__str__()))
continue
response = requests.post(url=url, data={'uploader': 'admin'}, files=files)
最终结果:
File: test_252.docx, Error: [Errno 24] Too many open files: '/Users/BonJu/Projects/downloads/test_252.docx'
File: test_253.docx, Error: [Errno 24] Too many open files: '/Users/BonJu/Projects/downloads/test_253.docx'
File: test_254.docx, Error: [Errno 24] Too many open files: '/Users/BonJu/Projects/downloads/test_254.docx'
...
File: test_418.docx, Error: [Errno 24] Too many open files: '/Users/BonJu/Projects/downloads/test_418.docx'
因为它是一个将发送的日志文件链接到问题的 API 服务器,所以我需要在一个请求中发送所有文件,否则经理会收到几封邮件并且无法解决问题。
这种情况有解决办法吗?
解决方案
我终于调整了我的 API,保存了一个临时文件来存储上传日志,并传递了一个 status 参数来控制最终输出。
我的代码:
payload = {
'status': 'finish',
'uploader': 'admin'
}
response = requests.post(url=url, data=payload, files=files)
API:
@api_view(['post'])
def upload(request, debug, api_version):
status = request.POST.get('status')
file_list = request.FILES.getlist('file')
if status == 'finish':
# open the temp file and insert the last logs then output
else:
# create/insert the logs and save to a temp file
return Response({'status': status, 'files': file_list})
【问题讨论】:
-
这能回答你的问题吗? Why should I close files in Python?
-
如果您需要将文件句柄传递给
requests.post并且无法在发送前关闭它们,则需要使用较少的文件进行多次请求。 -
@mkrieger1 OK~ 我认为这可能是适合我情况的最佳方式。谢谢。
标签: python file-upload python-requests