是否有一个Python模块用于透明地使用类文件对象作为缓冲区?

时间:2012-12-24 18:00:12

标签: python

我正在开发一个纯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可能不是最好的例子。它是一个特殊的案例,因为它是一个流媒体接口。 StringIObz2公开了一个更传统的seek / read / close界面,我个人经常使用这些界面。因此,我编写了一个模块,它将类文件对象包装为缓冲区。你可以查看here

1 个答案:

答案 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)