请求 - 如何流上传 - 部分文件

Gre*_*reg 13 python python-requests

我的目标是使用请求对文件的一部分进行PUT并流式传输文件(即,不将其加载到内存中然后执行PUT).

此页面说明了如何为整个文件执行此操作:

请求支持流式上传,允许您发送大型流或文件而无需将其读入内存.要进行流式传输和上传,只需为您的身体提供类似文件的对象:

with open('massive-body', 'rb') as f:
    requests.post('http://some.url/streamed', data=f)
Run Code Online (Sandbox Code Playgroud)

但是在我的情况下,我只想发送一个文件块.有没有办法实现这个目标?

在概念上,类似于:

with open('massive-body', 'rb') as f:
    requests.post('http://some.url/streamed', data=f.read(chunksize))
Run Code Online (Sandbox Code Playgroud)

Ian*_*sco 6

根据Greg对我的问题的回答,我认为以下内容最有效:

首先,您需要一些东西来打开您的打开文件,以便限制可以读取的数据量:

class FileLimiter(object):
    def __init__(self, file_obj, read_limit):
        self.read_limit = read_limit
        self.amount_seen = 0
        self.file_obj = file_obj

        # So that requests doesn't try to chunk the upload but will instead stream it:
        self.len = read_limit

    def read(self, amount=-1):
        if self.amount_seen >= self.read_limit:
            return b''
        remaining_amount = self.read_limit - self.amount_seen
        data = self.file_obj.read(min(amount, remaining_amount))
        self.amount_seen += len(data)
        return data
Run Code Online (Sandbox Code Playgroud)

这应该大致可以作为一个好的包装器对象.然后你会像这样使用它:

 with open('my_large_file', 'rb') as file_obj:
     file_obj.seek(my_offset)
     upload = FileLimiter(file_obj, my_chunk_limit)
     r = requests.post(url, data=upload, headers={'Content-Type': 'application/octet-stream'})
Run Code Online (Sandbox Code Playgroud)

标题显然是可选的,但是当将数据流式传输到服务器时,最好成为一个体贴的用户并告诉服务器您要发送的内容类型.


Joe*_*Joe 5

我只是将其他两个答案放在一起,所以如果它不能开箱即用,请耐心等待\xe2\x80\x94我无法测试这个:

\n

在Python中读取大文件的惰性方法?

\n

http://docs.python-requests.org/en/latest/user/advanced/#chunk-encoded-requests

\n
def read_in_chunks(file_object, blocksize=1024, chunks=-1):\n    """Lazy function (generator) to read a file piece by piece.\n    Default chunk size: 1k."""\n    while chunks:\n        data = file_object.read(blocksize)\n        if not data:\n            break\n        yield data\n        chunks -= 1\n\n\nrequests.post(\'http://some.url/chunked\', data=read_in_chunks(f))\n
Run Code Online (Sandbox Code Playgroud)\n