您的位置:首页 >如何在 Go 中实现文件下载的暂停与续传功能
发布于2026-04-08 阅读(0)
扫一扫,手机访问

本文详解如何在 Go 语言中为 HTTP 文件下载添加真正的暂停(取消)与续传(Range 请求)能力,涵盖 http.Request.Cancel 的正确用法、断点续传的核心原理、Range 头设置、本地文件偏移写入及关键注意事项。
本文详解如何在 Go 语言中为 HTTP 文件下载添加真正的暂停(取消)与续传(Range 请求)能力,涵盖 `http.Request.Cancel` 的正确用法、断点续传的核心原理、Range 头设置、本地文件偏移写入及关键注意事项。
在 Go 中,“暂停下载”并非字面意义的线程挂起,而是主动取消当前请求;而“续传”本质上是发起新的 HTTP GET 请求,并通过 Range 请求头告知服务器从指定字节位置继续传输。这要求服务端支持 Accept-Ranges: bytes(绝大多数静态文件服务器默认支持),且客户端需维护已下载的字节数与本地文件状态。
package main
import (
"context"
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
)
func downloadWithResume(url, filepath string, resume bool) error {
var offset int64 = 0
if resume {
if fi, err := os.Stat(filepath); err == nil {
offset = fi.Size()
}
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return err
}
// 设置 Range 头(仅续传时)
if offset > 0 {
req.Header.Set("Range", fmt.Sprintf("bytes=%d-", offset))
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusPartialContent {
return fmt.Errorf("unexpected status: %s (%d)", resp.Status, resp.StatusCode)
}
// 确保以追加模式打开(或 seek 到 offset)
f, err := os.OpenFile(filepath, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close()
if offset > 0 {
if _, err := f.Seek(offset, io.SeekStart); err != nil {
return fmt.Errorf("seek failed: %w", err)
}
}
// 复制数据
n, err := io.Copy(f, resp.Body)
if err != nil && err != io.EOF {
return fmt.Errorf("copy failed: %w", err)
}
fmt.Printf("Downloaded %d additional bytes\n", n)
return nil
}
// 使用示例
func main() {
url := "https://httpbin.org/bytes/1000000"
file := "download.bin"
// 首次下载(不 resume)
fmt.Println("Starting initial download...")
if err := downloadWithResume(url, file, false); err != nil {
panic(err)
}
// 模拟暂停后续传(例如用户点击“继续”)
fmt.Println("Resuming download...")
if err := downloadWithResume(url, file, true); err != nil {
panic(err)
}
}Go 中的“暂停/续传”是基于 HTTP 协议语义的协作式机制,而非操作系统级挂起。掌握 context 取消、Range 头构造、文件偏移写入三者联动,即可构建健壮的断点续传下载器。建议进一步封装为结构体(如 Downloader),支持进度回调、错误重试和校验和验证,以满足生产环境需求。
上一篇:Win10无线投屏电视教程详解
下一篇:逸剑风云决慧达支线攻略详解
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9