我正在开发一个纯Python解析器,其输入数据的大小范围可以从千字节到千兆字节。是否有一个包装文件类对象的模块,并将显式的.open()/。seek()/。read()/。close()调用抽象为一个类似缓冲区的简单对象?您可能会将此视为StringIO的反转。我希望它看起来像:
with FileLikeObjectBackedBuffer(urllib.urlopen("http://www.google.com")) as buf:
header = buf[0:0x10]
footer = buf[-0x10:]
注意,昨天我问了一个similar quesetion,并接受了mmap
个文件。在这里,我特意寻找一个包装文件类对象的模块(为了参数,比如urllib
返回的那个)。
更新
自从我第一次提出问题以来,我一再回到这个问题,事实证明urllib
可能不是最好的例子。它是一个特殊的案例,因为它是一个流媒体接口。 StringIO
和bz2
公开了一个更传统的seek
/ read
/ close
界面,我个人经常使用这些界面。因此,我编写了一个模块,它将类文件对象包装为缓冲区。你可以查看here。
答案 0 :(得分:4)
虽然urllib.urlopen
返回类似文件的obj,但我不相信你可以在不编写自己的情况下做你想做的事情 - 例如它不支持seek
但支持{ {1}},next
等等......既然你正在处理一个只有前进的流 - 你必须通过检索来处理跳转,直到你到达某一点并缓存任何回溯。
恕我直言 - 你无法有效地跳过网络IO流的一部分(如果你想要最后一个字节,你仍然必须得到所有以前的字节才能到达那里 - 你如何管理该存储取决于你)。
我很想read
(或类似)文件,urlretrieve
根据您之前的回答。
如果您的服务器可以接受mmap
(并且响应大小已知并且根据您的示例来自该派生块),那么可能的解决方法是使用http://en.wikipedia.org/wiki/Byte_serving(但不能说我曾经试过这个。)
举个例子,如果你只想要前16和后16,并且不想做“过于花哨”的事情:
ranges
输出:
from string import ascii_lowercase
from random import choice
from StringIO import StringIO
buf = ''.join(choice(ascii_lowercase) for _ in range(50))
print buf
sio_buf = StringIO(buf) # make it a bit more like a stream object
first16 = sio_buf.read(16)
print first16
from collections import deque
last16 = deque(iter(lambda: sio_buf.read(1), ''), 16) # read(1) may look bad but it's buffered anyway - so...
print ''.join(last16)