Golang下载文件

远航
2022-04-27 / 0 评论 / 133 阅读 / 正在检测是否收录...
直接上代码,想知道每行什么意思就自己百度去,工具类不详细说明
package down

import (
    "io"
    "net/http"
    "os"
    "path/filepath"
)

type WriteCounter struct {
    FileName string
    Total    uint64
}

func (wc *WriteCounter) Write(p []byte) (int, error) {
    n := len(p)
    wc.Total += uint64(n)
    wc.PrintProgress()
    return n, nil
}

func (wc WriteCounter) PrintProgress() {
    //fmt.Printf("\r%s", strings.Repeat(" ", 35))
    //fmt.Printf("\rDownloading %s %s complete", wc.FileName, humanize.Bytes(wc.Total))
}

func DownloadFile(filePath string, url string) error {
    fn := filepath.Base(filePath)
    out, err := os.Create(filePath + ".tmp")
    if err != nil {
        return err
    }
    resp, err := http.Get(url)
    if err != nil {
        _ = out.Close()
        return err
    }
    defer resp.Body.Close()
    counter := &WriteCounter{FileName: fn}
    if _, err = io.Copy(out, io.TeeReader(resp.Body, counter)); err != nil {
        _ = out.Close()
        return err
    }
    _ = out.Close()
    if err = os.Rename(filePath+".tmp", filePath); err != nil {
        return err
    }
    return nil
}

func DownloadFileHasHeader(filepathStr string, urlS string, headerMap map[string]string, proxyIp []string) error {
    fn := filepath.Base(filepathStr)
    request, err := http.NewRequest("GET", urlS, nil)
    if err != nil {
        return err
    }

    // 设置请求头
    for k, v := range headerMap {
        request.Header.Add(k, v)
    }
    client := &http.Client{}

    //是否使用代理IP
    if len(proxyIp) > 0 {
        rand := grand.N(1, len(proxyIp))
        proxy := func(_ *http.Request) (*url.URL, error) {
            return url.Parse(proxyIp[rand])
        }
        transport := &http.Transport{Proxy: proxy}
        client = &http.Client{Transport: transport}
    } else {
        client = &http.Client{}
    }
    httpResponse, getErr := client.Do(request)
    if getErr != nil {
        return getErr
    }
    resp, zErr := switchContentEncoding(httpResponse)
    if zErr != nil {
        return zErr
    }
    out, err := os.Create(filepathStr + ".tmp")
    if err != nil {
        return err
    }
    counter := &WriteCounter{FileName: fn}
    if _, err = io.Copy(out, io.TeeReader(resp, counter)); err != nil {
        _ = out.Close()
        return err
    }
    _ = out.Close()
    if err = os.Rename(filepathStr+".tmp", filepathStr); err != nil {
        return err
    }
    return nil
}

func switchContentEncoding(res *http.Response) (bodyReader io.Reader, err error) {
    switch res.Header.Get("Content-Encoding") {
    case "gzip":
        bodyReader, err = gzip.NewReader(res.Body)
    case "deflate":
        bodyReader = flate.NewReader(res.Body)
    default:
        bodyReader = res.Body
    }
    return
}
使用方式
down.DownloadFile("/储存位置/文件名.后缀名","http://下载地址")
1

评论

博主关闭了当前页面的评论