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

最简单的解决方案:不要使用 a BytesIO,你不需要它。

urllib2.Request.add_data期望它的参数是一个字符串,所以给它一个。

电话:

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

将整个文件读入内存,然后将其写入bytesio内存。这意味着你已经有了字符串,你不需要两次。所以试试:

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.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 回答
1

没有 BytesIO.getvalue() 方法,因为它不是必需的。相反,只需保留对底层缓冲区的引用。

这适用于列表和数组,以及字节对象,但这有点巧合,而不是实际的设计目标......

于 2012-06-14T14:44:38.903 回答
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 回答