简单的使用

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "os"
)

func main() {
    http.HandleFunc("/", downloadHandler) //   设置访问路由
    http.ListenAndServe(":8080", nil)
}
func downloadHandler(w http.ResponseWriter, r *http.Request) {
    fileName := "ceshi.png"  //filename  文件名
    path := "./data/images/" //文件存放目录防止用户下载其他目录文件
    file, err := os.Open(path + fileName)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()
    content, err := ioutil.ReadAll(file)
    fileNames := url.QueryEscape(fileName) // 防止中文乱码
    w.Header().Add("Content-Type", "application/octet-stream")
    w.Header().Add("Content-Disposition", "attachment; filename=\""+fileNames+"\"")
    if err != nil {
        fmt.Println("Read File Err:", err.Error())
    } else {
        w.Write(content)
    }
}

简单封装

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
    "path"
    "strconv"
    "strings"
)

func DownLoad(w http.ResponseWriter, r *http.Request) {
    DownLoadFileHandler(w, r, "./topgoer.rar", "./")
}
func main() {
    http.HandleFunc("/", DownLoad)
    err := http.ListenAndServe(":9090", nil)
    if err != nil {
        fmt.Println("HTTP server failed,err:", err)
        return
    }
}
func DownLoadFileHandler(w http.ResponseWriter, req *http.Request, fpath string, resPrefix string) {
    defer req.Body.Close()
    err := req.ParseForm()
    //request header
    ranStr := req.Header.Get("Range")
    fmt.Println("Range: " + ranStr)
    //    w.Header().Set("Access-Control-Allow-Origin", "*")
    if err != nil {
        w.Header().Set("Content-Type", " text/plain; charset=UTF-8")
        w.WriteHeader(http.StatusBadRequest)
        w.Write([]byte(err.Error()))
        return
    }
    if fpath == "" || !strings.HasPrefix(fpath, resPrefix) {
        w.Header().Set("Content-Type", " text/plain; charset=UTF-8")
        w.WriteHeader(http.StatusOK)
        w.Write([]byte("No file can be downloaded."))
        return
    }
    file, err := os.Open(fpath)
    if err != nil {
        w.Header().Set("Content-Type", " text/plain; charset=UTF-8")
        w.WriteHeader(http.StatusOK)
        w.Write([]byte(err.Error()))
        return
    }
    defer file.Close()
    //设置下载完成以后的名称
    aliasName := path.Base(fpath)
    w.Header().Set("Content-Disposition", "attachment; filename="+aliasName)
    //设置下载的偏移量
    fstat, _ := file.Stat()
    fsize := fstat.Size()
    var spos int64
    if ranStr != "" {
        rs := strings.Split(strings.TrimPrefix(ranStr, "bytes="), ",")[0]
        sePos := strings.Split(rs, "-")
        spStr := sePos[0]
        spos, _ = strconv.ParseInt(spStr, 0, 64)
        file.Seek(spos, 0)
    }
    fmt.Println(spos)
    w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", spos, fsize-1, fsize))
    w.Header().Set("Content-Length", fmt.Sprintf("%d", fsize-spos))
    //    w.WriteHeader(http.StatusPartialContent)
    if spos == 0 {
        w.WriteHeader(http.StatusOK)
    } else {
        w.WriteHeader(http.StatusPartialContent)
    }
    wcount, err := io.Copy(w, file)
    if err != nil {
        fmt.Println("io.Copy: ", err.Error())
    }
    if spos+wcount == fsize {
        fmt.Println("remove from cache info.")
        fmt.Println("delete finished file." + fpath)
        file.Close()
        err := os.Remove(fpath)
        if err != nil {
            fmt.Println(err)
        }
    }
}
文档更新时间: 2021-03-14 19:38   作者:kuteng