1

我正在使用Python avro 库。我想通过http发送一个avro文件,但我并不特别想先将该文件保存到磁盘,所以我想我会使用StringIO来存放文件内容,直到我准备好发送。但是 avro.datafile.DataFileWriter 周到地为我关闭了文件句柄,这让我很难从 StringIO 中取回数据。这就是我在代码中的意思:

from StringIO import StringIO
from avro.datafile import DataFileWriter
from avro import schema, io
from testdata import BEARER, PUBLISHURL, SERVER, TESTDATA
from httplib2 import Http

HTTP = Http()
##
# Write the message data to a StringIO
#
# @return StringIO
#
def write_data():
    message = TESTDATA
    schema = getSchema()
    datum_writer = io.DatumWriter(schema)
    data = StringIO()
    with DataFileWriter(data, datum_writer, writers_schema=schema, codec='deflate') as datafile_writer:
        datafile_writer.append(message)
        # If I return data inside the with block, the DFW buffer isn't flushed
        # and I may get an incomplete file
    return data

##
# Make the POST and dump its response
#
def main():
    headers = {
        "Content-Type": "avro/binary",
        "Authorization": "Bearer %s" % BEARER,
        "X-XC-SCHEMA-VERSION": "1.0.0",
    }
    body = write_data().getvalue() # AttributeError: StringIO instance has no attribute 'buf'
    # the StringIO instance returned by write_data() is already closed. :(
    resp, content = HTTP.request(
        uri=PUBLISHURL,
        method='POST',
        body=body,
        headers=headers,
    )
    print resp, content

我确实有一些我可以使用的解决方法,但它们都不是非常优雅。关闭后有什么方法可以从 StringIO 获取数据?

4

2 回答 2

3

并不真地。

文档对此非常清楚:

StringIO.close()

释放内存缓冲区。尝试对已关闭的 StringIO 对象执行进一步操作将引发 ValueError。

最干净的方法是从 StringIO 继承并覆盖该close方法以不执行任何操作:

class MyStringIO(StringIO):
   def close(self):
       pass
   def _close(self):
       super(MyStringIO, self).close()

_close()准备好后打电话。

于 2012-04-02T14:29:31.850 回答
1

我想做完全相同的事情,DataFileWriter 有一个刷新方法,所以你应该能够在调用 append 之后刷新,然后返回数据。对我来说似乎比从 StringIO 派生一个类更优雅。

于 2013-08-30T20:31:01.597 回答