如何使用 Go 高效下载大文件?

新手上路,请多包涵

有没有一种方法可以使用 Go 下载大文件,将内容直接存储到文件中,而不是在将其写入文件之前将其全部存储在内存中?因为文件太大,在写入文件之前将其全部存储在内存中会耗尽所有内存。

原文由 Cory 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 767
2 个回答

我假设您的意思是通过 http 下载(为简洁起见省略了错误检查):

 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)

http.Response 的主体是一个 Reader,因此您可以使用任何带有 Reader 的函数,例如,一次读取一个块而不是一次读取所有块。在这种特定情况下, io.Copy() 为您完成繁重的工作。

原文由 Steve M 发布,翻译遵循 CC BY-SA 3.0 许可协议

Steve 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
}

原文由 Pablo Jomer 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题