Python 分块阅读重反应
为了避免Python中的MemoryError,我尝试分块阅读。我已经花了半天的时间研究如何从Response中阅读语块,但没有结果 源代码是使用Dropbox SDK for python的类似文件的对象 以下是我的尝试:Python 分块阅读重反应,python,python-2.7,dropbox-api,Python,Python 2.7,Dropbox Api,为了避免Python中的MemoryError,我尝试分块阅读。我已经花了半天的时间研究如何从Response中阅读语块,但没有结果 源代码是使用Dropbox SDK for python的类似文件的对象 以下是我的尝试: import dropbox from filechunkio import FileChunkIO import math file_and_metadata = dropbox_client.metadata(path) hq_file = dropbox_clie
import dropbox
from filechunkio import FileChunkIO
import math
file_and_metadata = dropbox_client.metadata(path)
hq_file = dropbox_client.get_file(file_and_metadata['path'])
source_size = file_and_metadata['bytes']
chunk_size = 4194304
chunk_count = int(math.ceil(source_size / chunk_size))
for i in range(chunk_count + 1):
offset = chunk_size * i
bytes = min(chunk_size, source_size - offset)
with FileChunkIO(hq_file, 'r', offset=offset,
bytes=bytes) as fp:
with open('tmp/testtest123.mp4', 'wb') as f:
f.write(fp)
f.flush()
这将导致“TypeError:强制使用Unicode:需要字符串或缓冲区,找到重新响应”
任何线索或解决方案都将不胜感激。不知道任何关于
FileChunkIO
的信息,甚至不知道代码在哪里引发异常,很难确定,但我猜它需要一个真正的类似文件的对象。或者它做了一些愚蠢的事情,比如检查类型,这样它就可以决定是要把字符串分块还是要把文件分块
无论如何,根据文档,它不是一个完整的类似文件的对象,但它实现了read
和close
。您可以轻松地将实现读取
的内容分块,而无需任何花哨的包装。类文件对象的read
方法保证在到达EOF时返回b'
,并且返回的字节数比您要求的要少,因此您无需猜测需要读取多少次并在最后进行短暂读取。只要这样做:
chunk_size = 4194304
with open('tmp/testtest123.mp4', 'wb') as f:
while True:
buf = hq_file.read(chunk_size)
if not buf:
break
f.write(buf)
(请注意,我将open
移动到循环之外。否则,对于每个块,您将打开并清空文件,然后写入下一个块,因此最后只会得到最后一个块。)
如果您想要一个分块包装器,有一个非常好的内置函数,可以为您实现:
chunk_size = 4194304
chunks = iter(lambda: hq_file.read(chunk_size), '')
with open('tmp/testtest123.mp4', 'wb') as f:
f.writelines(chunks)
请注意,如果将Python3.x中的'
更改为b'
,则完全相同的代码可以在Python3.x中工作,但这破坏了Python2.5
这可能有点滥用了writelines
,因为我们正在编写一组实际上不是行的字符串。如果您不喜欢它,显式循环同样简单,而且简洁
我通常把它写成partial(hq\u file.read,chunk\u size)
而不是lambda:hq\u file.read(chunk_size
,但这确实是一个偏好的问题;阅读上面的文档,你应该能够理解为什么它们最终会产生相同的效果,并决定你更喜欢哪一个。请展示完整的回溯。是文件Chunkio
引起投诉,还是其他原因?