我正在尝试上传这样的文件:
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 作为文件对象传递而不是将其写入文件并传递文件名?这可能吗?
最佳答案
在完美的情况下,基本上可以连接两个流,但这不是一个非常可靠的解决方案。有一堆丑陋的边界条件:
- 响应套接字可能仍然是 接收数据,和/或停止, 从而导致你饿死 打破 POST(因为 PycURL 不是 预计必须等待数据 超出当前的结束 "file")。
- 响应可能会重置,然后您没有完整的文件,但您已经发布了一堆数据 - 在这种情况下该怎么办?
- 您使用 urllib 获取的文件可能是分块编码的,因此您需要对 MIME header 执行一些操作以进行重组 - 您不能只是盲目地转发数据。
- 您不一定知道您获得的文件有多大,因此很难在 POST 中提供正确的内容长度,因此您必须分块编写。
- 可能还有其他一些我想不起来的问题...
您最好暂时将文件写入磁盘,然后在您知道拥有完整文件后将其发布。
如果您确实想这样做,最好的方法可能是实现您自己的类文件对象,该对象将管理两个连接之间的桥梁(可以正确缓冲、处理解码等)。
编辑:
根据您留下的评论 - 当然 - 您只需要设置选项 READFUNCTION
。在以下位置查看 file_upload 示例:
它通过在文件对象上制作一个带有回调的微型包装器来从中读取数据,或者如果您不需要进行任何处理,您可以直接设置 READFUNCTION
回调为 fp.read
。
关于python - 使用 PyCurl 从文件对象上传文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2863406/