直接上代码,想知道每行什么意思就自己百度去,工具类不详细说明
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://下载地址")
评论