当包含的Writer()关闭它时,我还可以使用StringIO吗?

时间:2012-04-02 14:25:55

标签: python file buffer avro

我正在使用Python avro library。我想通过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关闭后从StringIO获取数据?

2 个答案:

答案 0 :(得分:3)

不是。

文档非常明确:

  

<强> StringIO.close()

     

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

最干净的方法是继承StringIO并覆盖close方法无所作为:

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

准备就绪后致电_close()

答案 1 :(得分:1)

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