2013-05-01 8 views
23

以下のコードをストリーム/パイプを使用するように変換すると、完全な内容をメモリに読み込む必要はありません。 のような何か: http.Get("http://example.com/").Pipe("./data.txt")GoでHTTP応答をファイルにパイプする方法はありますか?

package main 
import ("net/http";"io/ioutil") 

func main() { 
     resp, err := http.Get("http://example.com/") 
     check(err) 
     defer resp.Body.Close() 
     body, err := ioutil.ReadAll(resp.Body) 
     check(err) 
     err = ioutil.WriteFile("./data.txt", body, 0666) 
     check(err) 
} 
func check(e error) { 
     if e != nil { 
       panic(e) 
     } 
} 
+1

Getのレスポンスには、フィールドBody hatがReaderを実装しています。基本的には、これをファイルに書き込む何らかの関数に渡すことができます。あなたがそれを要求した場合を除いて、ボディの内容全体がメモリにロードされることはありません。 – fuz

答えて

38

いかがio.Copy()?そのドキュメントはhttp://golang.org/pkg/io/#Copy

で見つけることができます。それにio.Readerio.Writerを与え、一度に1つの小さなチャンク(例えば、一度にすべてをメモリに入れないなど)でデータをコピーします。

だから、のようなものを書いてみてください:私は上記をテストしていません

func main() { 
    resp, err := http.Get("...") 
    check(err) 
    defer resp.Body.Close() 
    out, err := os.Create("filename.ext") 
    if err != nil { 
    // panic? 
    } 
    defer out.Close() 
    io.Copy(out, resp.Body) 
} 

。私はちょうどあなたの上記の例からすぐにそれを一緒にハッキングしましたが、お金の上になければ近くにする必要があります。

+0

ありがとうございました。それは正常に動作しています! – ekanna

+3

このコードは 'Close()'ステートメントのいずれかのエラー戻りをチェックしないことに注意してください。 –

+3

@Nickこれは非常に一般的です(たとえ慣用的であっても)、エラーをクローズし無視するためです。通常、OSでの叫びを除いて、間違いなくあなたができることはあまりありません。 – mna

関連する問題