我尝试将二进制文件上传到Flask端点,而不使用任何类型的multipart/form-data
。我只想将POST
或PUT
文件中的数据简单地发送到端点,并将其保存到服务器上的文件中。我能找到的唯一例子,以及其他问题中讨论的唯一方法,使用multipart/form-data
。
以下"工作",但SHA256哈希通常不匹配,而上传form-data
则可以正常工作。
@application.route("/rupload/<filename>", methods=['POST', 'PUT'])
def rupload(filename):
# Sanity checks and setup skipped.
filename = secure_filename(filename)
fileFullPath = os.path.join(UPLOAD_FOLDER, filename)
with open(fileFullPath, 'wb') as f:
f.write(request.get_data())
return jsonify({
'filename': filename,
'size': os.path.getsize(fileFullPath)
})
此外,上述内存效率非常低。有没有办法通过某种类型的缓冲流将其写入输出文件?谢谢!
编辑:这就是我测试它的方式:
curl -v -H 'Content-Type: application/octet-stream' -X POST --data @test.zip https://example.com/test/rupload/test.zip
修改: --data-binary
没有任何区别。
答案 0 :(得分:1)
问题可能是您正在使用的curl命令。手册页推荐--data-binary:“这完全按照指定发布数据,无需任何额外处理。” --data参数是--data-ascii的同义词。可能不需要-X参数,因为它应默认为POST。
curl -v -H 'Content-Type: application/octet-stream' -X POST --data-binary @test.zip https://example.com/test/rupload/test.zip
request.get_data调用还有其他选项可以帮助他们在某处被覆盖。但看起来应该在服务器端工作。禁用缓存功能可能会使您的用例受益。
f.write(request.get_data(cache=False, as_text=False, parse_form_data=False))
如果是服务器端,您可能需要深入了解Werkzeug get_input_stream,这是请求对象的主要内容。
curl命令使用内容类型标头作为'application / octet-stream'是件好事。在这种情况下,Flask似乎没有对此做任何事情,但它可以帮助更广泛地使用代理或其他情况下的数据。
关于有效处理大文件,您可能需要查看request stream property,这是get_data在内部用于从中读取数据的内容。
答案 1 :(得分:1)
您是否尝试过使用hashlib?
import hashlib
...
@application.route("/rupload/<filename>", methods=['POST', 'PUT'])
def rupload(filename):
# Sanity checks and setup skipped.
filename = secure_filename(filename)
fileFullPath = os.path.join(UPLOAD_FOLDER, filename)
file_hash = hashlib.sha256()
with open(fileFullPath, 'wb+') as f:
input = request.get_data()
f.write(input)
file_hash.update(input)
...
fileDigest = file_hash.hexdigest()