在我的Flask应用程序中,路由通过HTTP PUT接受文件上传。由于这些文件将由外部工具处理,我需要将它们保存到磁盘。由于文件可能变得更大(几百MB),我避免使用request.get_data()
,而是使用request.stream
使用常量内存将传入数据写入磁盘:
现在我做
from tempfile import NamedTemporaryFile
from flask import send_file
# ...
@app.route('/<path>', methods=['PUT'])
def handle_upload(path):
try:
with NamedTemporaryFile(delete=False) as tmpFile:
while True:
chunk = request.stream.read(16384)
if not chunk:
break
tmpFile.write(chunk)
processFile(tmpFile.name) # This calls out to an external tool
return send_file(tmpFile.name)
finally:
os.remove(tmpFile.name)
然而,看到Flask提供了诸如send_file
之类的便利方法,我想知道:Flask或Werkzeug是否可以提供现成的功能来将请求的数据流式传输到文件中,这比手工短 - 书面循环?我怀疑我可能会忽略API文档中的某些内容。
答案 0 :(得分:1)
我遇到了同样的问题,但是发现了一个更好的alternative:以与POST上传相同的方式进行处理,并将流转换为werkzeug.FileStorage
incoming = FileStorage(request.stream)
with NamedTemporaryFile(delete=False) as tmpFile:
incoming.save(tmpFile)
请注意save
的描述:
将文件保存到目标路径或文件对象。如果目标是文件对象,则必须在调用后自行关闭它。缓冲区大小是复制过程中保存在内存中的字节数。默认为16KB。
答案 1 :(得分:0)
在研究了更多人并与不同的人交谈之后,在我看来,在块中读取request.stream
是将PUT请求的数据保存到文件的最佳方式,即
for chunk in iter(lambda: request.stream.read(16384), bytes()):
f.write(chunk)