1

我正在尝试上传这样的文件:

import pycurl

c = pycurl.Curl()

values = [
     ("name", "tom"),
     ("image", (pycurl.FORM_FILE, "tom.png"))
]

c.setopt(c.URL, "http://upload.com/submit")
c.setopt(c.HTTPPOST, values)
c.perform()
c.close()

这工作正常。但是,这仅在文件是本地文件时才有效。如果我要获取这样的图像:

import urllib2
resp = urllib2.urlopen("http://upload.com/people/tom.png")

如何将 resp.fp 作为文件对象传递,而不是将其写入文件并传递文件名?这可能吗?

4

1 回答 1

4

在完美的情况下可能基本上连接两个流,但这不是一个非常强大的解决方案。有一堆丑陋的边界条件:

  • 响应套接字可能仍在接收数据,和/或停止,从而导致您饿死并中断 POST(因为 PycURL 不希望必须等待超出“文件”当前结尾的数据)。
  • 响应可能会重置,然后您没有完整的文件,但您已经发布了一堆数据 - 在这种情况下该怎么办?
  • 您使用 urllib 获取的文件可能是分块编码的,因此您需要对 MIME 标头执行一些操作以进行重组 - 您不能只是盲目地转发数据。
  • 您不一定知道要获取的文件有多大,因此很难在 POST 上提供正确的内容长度,因此您必须编写分块。
  • 可能还有一堆其他的问题,我想不出来...

最好将文件暂时写入磁盘,然后在您知道自己拥有全部内容后将其发布。

如果您确实想这样做,最好的方法可能是实现您自己的类似文件的对象,该对象将管理两个连接之间的桥梁(可以正确缓冲、处理解码等)。

编辑:

根据您留下的评论 - 绝对 - 您只需要 setopt READFUNCTION。在以下位置查看 file_upload 示例:

http://pycurl.cvs.sourceforge.net/viewvc/pycurl/pycurl/examples/file_upload.py?revision=1.5&view=markup

它通过在文件对象上创建一个带有回调的小包装器来实现这一点,以从中读取数据,或者如果您不需要进行任何处理,您可以将READFUNCTION回调设置为fp.read.

于 2010-05-19T07:42:58.617 回答