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

基本的に2つのストリームを接続することは完璧な状況で可能かもしれませんが、それは非常に堅牢なソリューションではありません。醜い境界条件がたくさんあります:

  • 応答ソケットはまだデータを受信して​​いる、または停止している可能性があります。そのため、POSTが不足して中断する可能性があります(PycURLは「ファイル」の現在の終わりを超えるデータを待機する必要がないため)。
  • 応答がリセットされ、完全なファイルがない可能性がありますが、すでに大量のデータをPOSTしています-この場合はどうすればよいですか?
  • urllibでフェッチしているファイルはチャンクエンコードされている可能性があるため、再構成のためにMIMEヘッダーに対していくつかの操作を実行する必要があります。データを盲目的に転送することはできません。
  • 取得するファイルのサイズが必ずしもわからないため、POSTで適切なコンテンツ長を指定するのは難しいため、チャンクで書き込む必要があります。
  • おそらく、頭のてっぺんからは考えられない他の問題がたくさんあります...

ファイルを一時的にディスクに書き込んでから、すべてが揃ったらPOSTする方がはるかに良いでしょう。

これを実行したい場合は、2つの接続間のブリッジを管理する(適切にバッファリング、デコードを処理できるなど)独自のファイルのようなオブジェクトを実装するのがおそらく最善の方法です。

編集:

あなたが残したコメントに基づいて-絶対に-あなたはただ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 に答える