Go下载文件核心是安全可控地搬运HTTP字节流:基础用http.Get+io.Copy流式写入;生产需自定义超时client;支持Range断点续传;可加TeeReader实现进度显示。
使用 Go 的 net/http 包下载文件非常直接,核心是发起 HTTP GET 请求,读取响应体,并写入本地文件。关键在于正确处理连接、错误、大文件流式写入,以及可选的进度反馈和重试逻辑。
最简方式是用 http.Get 获取响应,再用 io.Copy 将响应体(resp.)流式写入打开的文件。这种方式内存友好,不把整个文件加载进内存。
Body
resp.StatusCode,避免静默下载错误页(如 404、500)defer resp.Body.Close() 防止连接泄漏os.Create 创建文件,注意处理路径不存在的情况(可用 os.MkdirAll 预创建目录)http.Get 使用默认客户端,无法设置超时或重试。生产环境应构造带超时的 http.Client:
Timeout 防止请求无限挂起(建议 30 秒以内)Transport 控制最大连接数、空闲连接超时等client.Do(req) 而非 http.Get,便于添加请求头(如 User-Agent、认证 Token)若需支持中断后继续下载,需利用 HTTP Range 头。步骤如下:
file.Stat().Size())req.Header.Set("Range", fmt.Sprintf("bytes=%d-", downloaded))
206 Partial Content
os.OpenFile(..., os.O_WRONLY|os.O_APPEND) 方式打开文件追加写入对大文件,用户常关心下载进度。可在写入文件时统计已写入字节数:
io.TeeReader(resp.Body, progressWriter) 或自定义 io.Reader 包装器,在每次 Read 后更新计数fmt.Printf("\r%v / %v bytes", done, total) 实现覆盖式刷新(注意判断 resp.ContentLength 是否 > 0)io.Copy 到断点续传,都是围绕这个核心展开。