我的目标是使用请求对文件的一部分进行放置,并对该文件进行流式处理(即,不将其加载到内存中,然后进行放置)。
This page解释如何对整个文件执行此操作:
请求支持流式上载,允许您发送大量
流或文件而不将其读取到内存中。流和
上载,只需为您的身体提供类似文件的对象:

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

但是在我的例子中,我只想发送文件的一部分。有办法做到这一点吗?
在概念上,类似于:
with open('massive-body', 'rb') as f:
    requests.post('http://some.url/streamed', data=f.read(chunksize))

最佳答案

根据格雷格对我问题的回答,我认为以下几点最好:
首先,您需要一些东西来包装打开的文件,以便限制可以读取的数据量:

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

这应该大致可以作为一个好的包装器对象。然后您可以这样使用它:
 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'})

头文件显然是可选的,但是当数据流传输到服务器时,作为一个体贴的用户并告诉服务器您发送的内容类型是一个好主意。

关于python - 请求 - 如何流上传 - 部分文件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29775247/

10-14 09:36
查看更多