转:文件的断点下载服务端

原文地址:https://www.yuque.com/yss930819/guqz9f/aly0lz

golang #代码片段 #文件服务 #下载 #goframe

文件的断点续传,需要使用到 HTTP 协议的 206 状态码 实现文件的断点续传,具体的原理在网上可以找到一堆。网上找的所有 golang 代码都缺少一个步骤 flush 即将文件的内容写入后应主动将内容发送到客户端 即代码 39行 内容。

在研究了 java 的实现后,发现所有的 golang 实现都没有用 flush 不知道是 golang 本身提供的 net/http 里的 writer 已经实现了写入即 flush 的功能。

我们使用的 goframe 框架进行开发,在断点续传时需要做如下处理。PS:已使用迅雷和

参考的网站有
https://www.cnblogs.com/peteremperor/p/14081050.html
https://blog.csdn.net/zgh670042085/article/details/84416227

func download(r *ghttp.Request) {
	f,_ := gfile.Open("D:\\Windows.iso")
	info, _:= f.Stat()
	r.Response.Header().Add("Accept-Ranges", "bytes")
	r.Response.Header().Add("Content-Disposition", "attachment; filename="+info.Name())
	var start, end int64
	//fmt.Println(request.Header,"\n")
	if rangeBytes := r.Header.Get("Range"); rangeBytes != "" {
		if strings.Contains(rangeBytes, "bytes=") && strings.Contains(rangeBytes, "-") {
			fmt.Sscanf(rangeBytes, "bytes=%d-%d", &start, &end)
			if end == 0 {
				end = info.Size() - 1
			}
			r.Response.Header().Add("Content-Length", strconv.FormatInt(end-start+1, 10))
			r.Response.Header().Add("Content-Range", fmt.Sprintf("bytes %v-%v/%v", start, end, info.Size()))
			r.Response.WriteHeader(http.StatusPartialContent)
		} else {
			r.Response.WriteHeader(http.StatusBadRequest)
			return
		}
	} else {
		r.Response.Header().Add("Content-Length", strconv.FormatInt(info.Size(), 10))
		start = 0
		end = info.Size() - 1
	}
	_, _ = f.Seek(start, 0)
	n := 1024 * 1024
	buf := make([]byte, n)
	for {
		if end-start+1 < int64(n) {
			n = int(end - start + 1)
		}
		_, err := f.Read(buf[:n])
		if err != nil {
		
		}
		err = nil
		r.Response.Write(buf[:n])
		r.Response.Flush()
		start += int64(n)
		if start >= end+1 {
			return
		}
	}
	
}
posted @   卓能文  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示