2012-07-27 25 views

cevap

167

ben http üzerinden indirmek (kısaca geçilmiştir hata kontrolleri) demek varsayıyoruz:

import ("net/http"; "io"; "os") 
... 
out, err := os.Create("output.txt") 
defer out.Close() 
... 
resp, err := http.Get("http://example.com/") 
defer resp.Body.Close() 
... 
n, err := io.Copy(out, resp.Body) 

size bir Reader alır herhangi bir işlev kullanabilmesi http.Response en Vücut, bir okuyucu olduğunu Örneğin Bir kerede bir kerede bir yığın okumak. Bu özel durumda, io.Copy() sizin için gruntwork yapar.

+55

'io.Copy' girişten 32kb (maksimum) okur ve bunları çıktıya yazar, sonra tekrar eder. Yani hafıza hakkında endişelenme. –

-3
  1. İşte bir örnek. https://github.com/thbar/golang-playground/blob/master/download-files.go

  2. Ayrıca bazı kodların size yardımcı olabileceğini düşünüyorum.

kodu: Steve M'in cevabın

func HTTPDownload(uri string) ([]byte, error) { 
    fmt.Printf("HTTPDownload From: %s.\n", uri) 
    res, err := http.Get(uri) 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer res.Body.Close() 
    d, err := ioutil.ReadAll(res.Body) 
    if err != nil { 
     log.Fatal(err) 
    } 
    fmt.Printf("ReadFile: Size of download: %d\n", len(d)) 
    return d, err 
} 

func WriteFile(dst string, d []byte) error { 
    fmt.Printf("WriteFile: Size of download: %d\n", len(d)) 
    err := ioutil.WriteFile(dst, d, 0444) 
    if err != nil { 
     log.Fatal(err) 
    } 
    return err 
} 

func DownloadToFile(uri string, dst string) { 
    fmt.Printf("DownloadToFile From: %s.\n", uri) 
    if d, err := HTTPDownload(uri); err == nil { 
     fmt.Printf("downloaded %s.\n", uri) 
     if WriteFile(dst, d) == nil { 
      fmt.Printf("saved %s as %s\n", uri, dst) 
     } 
    } 
} 
+10

Bu örnek, tüm içeriğini ioutil.ReadAll() 'ile belleğe okur. Küçük dosyalar ile uğraştığın sürece sorun değil. – eduncan911

+9

@ eduncan911, ancak büyük dosyalar hakkında açıkça konuştuğu ve hepsini belleğe almayı istemediği bu soru için iyi değil. –

+1

Tam olarak doğru, bu yüzden yorum yaptım - başkalarının bunu büyük dosyalar için kullanmamalarını da bilmeleri için. – eduncan911

27

Bir daha açıklayıcı sürümü.

import (
    "os" 
    "net/http" 
    "io" 
) 

func downloadFile(filepath string, url string) (err error) { 

    // Create the file 
    out, err := os.Create(filepath) 
    if err != nil { 
    return err 
    } 
    defer out.Close() 

    // Get the data 
    resp, err := http.Get(url) 
    if err != nil { 
    return err 
    } 
    defer resp.Body.Close() 

    // Check server response 
    if resp.StatusCode != http.StatusOK { 
    return fmt.Errorf("bad status: %s", resp.Status) 
    } 

    // Writer the body to file 
    _, err = io.Copy(out, resp.Body) 
    if err != nil { 
    return err 
    } 

    return nil 
} 
7

io.Copy kullanarak yukarıdaki seçilen cevap İhtiyacınız ama kırık indirmeleri, otomatik adlandırma dosyaları, sağlama toplamı doğrulaması sürdürme veya çoklu indirme ilerlemesini izleme gibi ek özellikler ilginizi çekiyorsa, grab paketini ödeme tam olarak ne olduğunu.

İlgili konular