首页 > 解决方案 > 如何在请求中流式传输文件?

问题描述

我们有一个react与 django 后端通信的应用程序。每当react应用程序想要将文件上传到后端时,我们都会发送一个表单请求,其中一个字段是要上传的文件的句柄。该字段在 Django 端作为 接收 InMemoryUploadedFile,这是一个带有 some 的对象chunks,可以像这样处理:

def save_uploaded_file(uploaded_file, handle):
    """
    Saves the uploaded file using the given file handle.
    We walk the chunks to avoid reading the whole file in memory
    """
    for chunk in uploaded_file.chunks():
        handle.write(chunk)
    handle.flush()
    logger.debug(f'Saved file {uploaded_file.name} with length {uploaded_file.size}')

现在,我正在创建一些测试框架requests来驱动我们的 API。我试图模拟这种机制,但奇怪的是,它requests坚持在发送请求之前从打开的句柄中读取。我在做:

requests.post(url, data, headers=headers, **kwargs)

和:

data = {'content': open('myfile', 'rb'), ...}

请注意,我不是从文件中读取,我只是在打开它。但是requests坚持要从中读取,并发送嵌入的数据,这有几个问题:

我不希望这样:我只想requests“流式传输”该文件,而不是阅读它。有一个 files 参数,但这将创建一个包含嵌入在请求中的文件的 multipart,这又不是我想要的。我希望数据中的所有字段都在请求中传递,并且内容字段要流式传输。我知道这是可能的,因为:

如何强制请求流式传输数据中的特定文件?

标签: pythondjangostreampython-requests

解决方案


可能,这不再相关,但我将分享一些我在文档中找到的信息。

默认情况下,如果上传的文件小于 2.5 兆字节,Django 会将上传的全部内容保存在内存中。这意味着保存文件只涉及从内存读取和写入磁盘,因此非常快。但是,如果上传的文件太大,Django 会将上传的文件写入存储在系统临时目录中的临时文件中。

这样,就无需创建流式文件上传。相反,解决方案可能是使用缓冲区处理(读取)加载的内容。


推荐阅读