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 = 0end = info.Size() - 1}_, _ = f.Seek(start, 0)n := 1024 * 1024buf := make([]byte, n)for {if end-start+1 < int64(n) {n = int(end - start + 1)}_, err := f.Read(buf[:n])if err != nil {}err = nilr.Response.Write(buf[:n])r.Response.Flush()start += int64(n)if start >= end+1 {return}}}
