gpt4 book ai didi

python - 服务大文件的 Django Filewrapper 内存错误,如何流式传输

转载 作者:行者123 更新时间:2023-12-05 08:54:39 25 4
gpt4 key购买 nike

我有这样的代码:

@login_required
def download_file(request):
content_type = "application/octet-stream"
download_name = os.path.join(DATA_ROOT, "video.avi")

with open(download_name, "rb") as f:
wrapper = FileWrapper(f, 8192)
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Disposition'] = 'attachment; filename=blabla.avi'
response['Content-Length'] = os.path.getsize(download_name)
# response['Content-Length'] = _file.size
return response

看来是可行的。但是,如果我下载更大的文件(例如 ~600MB),我的内存消耗将增加 600MB。几次这样的下载后,我的服务器抛出:

Internal Server Error: /download/ Traceback (most recent call last):
File "/home/matous/.local/lib/python3.5/site-packages/django/core/handlers/exception.py", line 35, in inner response = get_response(request) File "/home/matous/.local/lib/python3.5/site-packages/django/core/handlers/base.py", line 128, in _get_response response = self.process_exception_by_middleware(e, request) File "/home/matous/.local/lib/python3.5/site-packages/django/core/handlers/base.py", line 126, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/home/matous/.local/lib/python3.5/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view return view_func(request, *args, **kwargs) File "/media/matous/89104d3d-fa52-4b14-9c5d-9ec54ceebebb/home/matous/phd/emoapp/emoapp/mainapp/views.py", line 118, in download_file response = HttpResponse(wrapper, content_type=content_type) File "/home/matous/.local/lib/python3.5/site-packages/django/http/response.py", line 285, in init self.content = content File "/home/matous/.local/lib/python3.5/site-packages/django/http/response.py", line 308, in content content = b''.join(self.make_bytes(chunk) for chunk in value) MemoryError

我做错了什么?是否可以以某种方式配置它,以便在没有这种疯狂的内存存储的情况下从硬盘驱动器逐段流式传输它?

注意:我知道 Django 不应提供大文件,但我正在寻找允许验证用户对任何提供的文件的访问权限的简单方法。

最佳答案

尝试使用StreamingHttpResponse相反,这会有所帮助,这正是您要找的。

是否可以通过某种方式将其配置为从硬盘逐段流式传输,而无需这种疯狂的内存存储?

import os
from django.http import StreamingHttpResponse
from django.core.servers.basehttp import FileWrapper #django <=1.8
from wsgiref.util import FileWrapper #django >1.8

@login_required
def download_file(request):
file_path = os.path.join(DATA_ROOT, "video.avi")
filename = os.path.basename(file_path)
chunk_size = 8192
response = StreamingHttpResponse(
FileWrapper(open(file_path, 'rb'), chunk_size),
content_type="application/octet-stream"
)
response['Content-Length'] = os.path.getsize(file_path)
response['Content-Disposition'] = "attachment; filename=%s" % filename
return response

这将以 block 的形式流式传输您的文件,而无需将其加载到内存中;或者,您可以使用 FileResponse ,

which is a subclass of StreamingHttpResponse optimized for binary files.

关于python - 服务大文件的 Django Filewrapper 内存错误,如何流式传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48949022/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com