1

Pythonavroライブラリを使用しています。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にはflushメソッドがあるので、appendの呼び出し後にフラッシュして、データを返すことができるはずです。StringIOからクラスを派生させるよりも、私には少しエレガントに思えます。

于 2013-08-30T20:31:01.597 に答える