2013-05-01 53 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 2013-05-01 01:05:52

回答

38

如何io.Copy()?它的文檔可以在:http://golang.org/pkg/io/#Copy

雖然這很簡單。給它一個io.Reader和一個io.Writer,它將數據一次複製一個小塊(例如,不是一次全部存儲在內存中)。

所以,你可以嘗試寫這樣的:

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 2013-05-01 01:22:58

+3

請注意,此代碼不檢查任何「Close()」語句的錯誤返回。 – 2013-05-01 07:45:07

+3

@Nick這很常見(甚至是慣用的),但是,推遲關閉並忽略錯誤。除了在操作系統上發出尖叫之外,通常沒有太多的事情可以處理。 – mna 2013-05-01 17:37:03