我正在使用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获取数据?
答案 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派生一个类更优雅。