0

さまざまなバイトを追加する BytesIO があります。request.add_data メソッドを介して urllib2.Request でこれを送信したい。どうすればいいですか?やってみると

# create request ....
bytesio = BytesIO()
bytesio.write(open("C:\img.jpg", "rb").read())
request.add_data(bytesio.getvalue()) 
bytesio.close()

urllib2.urlopen(request) # error "expected buffer, got bytes"

私は何を間違っていますか?Python は初めてで、BytesIO からバッファを作成する方法がわかりません。また、試してみると:

request.add_data(bytesio)  # instead of bytesio.getvalue()

「閉じたファイルに対する I/O 操作」が表示されます。urlopen の後で bytesio.close を呼び出すまで待機しようとすると、bytesio が閉じられるのを待っているため、要求がハングします。

私は何をする必要がありますか?

答え

request.add_data(str(btyesio.getvalue()))
bytesio.close()

文字列へのキャストはそれを幸せにしました。すべてが StringIO で機能するかどうかは試していませんし、Python 2.x と 3.x の違いも試していません。

4

4 に答える 4

2

最も簡単な解決策: を使用しBytesIOないでください。必要ありません。

urllib2.Request.add_dataは引数が文字列であることを期待しているので、1 つだけ指定してください。

呼び出し:

bytesio.write(open("C:\img.jpg", "rb").read())

bytesioファイル全体をメモリに読み込み、 s メモリに書き込みます。つまり、既に mory に文字列が含まれているため、2 回必要はありません。だから試してみてください:

request = urllib2.Request('http://www.site.com')
with open("C:\img.jpg", "rb") as inputfile:
    request.add_data(inputfile.read())
urllib2.urlopen(request)
于 2012-06-14T06:33:08.380 に答える
1

BytesIO.getvalue()メソッドは必要ないため、ありません。代わりに、基になるバッファへの参照を保持してください。

これは、リストと配列、およびバイトオブジェクトで機能しますが、実際の設計目標ではなく、一種の偶然です...

于 2012-06-14T14:44:38.903 に答える
1

この行を削除するだけです(最後に追加してください):

bytesio.close()

他のコードは私のために働くようです:

bytesio = BytesIO()
bytesio.write(open("C:\img.jpg", "rb").read())
request = urllib2.Request('http://www.site.com')
request.add_data(bytesio.getvalue()) 

urllib2.urlopen(request) # error "expected buffer, got bytes"
bytesio.close()

>>In [30]: urllib2.urlopen(request)
Out[30]: <addinfourl at 52264040 whose fp = <socket._fileobject object at 0x315a450>>

または StringIO を使用します。

sio = StringIO.StringIO(open("C:\img.jpg", "rb").read())
request = urllib2.Request('http://www.site.com')
request.add_data(sio.getvalue()) 

urllib2.urlopen(request) # error "expected buffer, got bytes"
sio.close()

>>In [14]: urllib2.urlopen(request)
Out[14]: <addinfourl at 49067360 whose fp = <socket._fileobject object at 0x2dfb3d0>>
于 2012-06-13T18:01:49.883 に答える
0

次の方法で a のデータ全体を取得できますBytesIO

esio.seek(0, os.SEEK_SET)
esio.read()

SEEK_SET必要ありませんが、物事を明確にするために使用します)

だからあなたの例:

# create request ....
bytesio = BytesIO()
bytesio.write(open("C:\img.jpg", "rb").read())
bytesio.seek(0, os.SEEK_SET)
request.add_data(bytesio.read()) 
bytesio.close()

urllib2.urlopen(request)
于 2012-06-16T14:58:52.123 に答える