【问题标题】:Uploading file from file object with PyCurl使用 PyCurl 从文件对象上传文件
【发布时间】:2010-05-19 06:47:27
【问题描述】:

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

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 作为文件对象传递,而不是将其写入文件并传递文件名?这可能吗?

【问题讨论】:

    标签: python pycurl


    【解决方案1】:

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

    • 响应套接字可能仍然是 接收数据,和/或停止, 从而导致你饿死 打破 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.

    【讨论】:

    • 这可能不是最好的例子,因为这不是我做事的方式。我的观点是文件内容已经可以通过文件对象获得,所以我想知道是否有另一种方法可以将该文件句柄传递给 PyCurl 而不是传递文件名。
    • @Tom:查看我编辑的回复 - 如果您已经拥有一个强大的文件对象,那么您要做的实际上是微不足道的。
    猜你喜欢
    • 2011-06-21
    • 2016-11-18
    • 1970-01-01
    • 2013-06-04
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 2012-03-22
    相关资源
    最近更新 更多