Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

博客无法评论 #40

Open
xiebruce opened this issue Aug 23, 2023 · 0 comments
Open

博客无法评论 #40

xiebruce opened this issue Aug 23, 2023 · 0 comments

Comments

@xiebruce
Copy link

我是在这个网站https://www.kandaoni.com/news/7733.html 来到这里的,我不知道网站站长是不是就是这个博客的开发者?目前https://www.kandaoni.com/news/7733.html 无法评论,一评论就报错

image

另外我对这篇文章中的download方法有疑问(新手),download方法都是在goroutine中运行的go d.Download(resource, p),那么该方法中return的err真的有用吗?我感觉没用吧,需要通过channel传出来才行吧?

package main
import (
    "fmt"
    "github.com/vbauerster/mpb/v5"
    "github.com/vbauerster/mpb/v5/decor"
    "io"
    "net/http"
    "os"
    "runtime"
    "strconv"
    "sync"
)
type Resource struct {
    Filename string
    Url      string
}
type Downloader struct {
    wg         *sync.WaitGroup
    pool       chan *Resource
    Concurrent int
    HttpClient http.Client
    TargetDir  string
    Resources  []Resource
}
func NewDownloader(targetDir string) *Downloader {
    concurrent := runtime.NumCPU()
    return &Downloader{
        wg:         &sync.WaitGroup{},
        TargetDir:  targetDir,
        Concurrent: concurrent,
    }
}
func (d *Downloader) AppendResource(filename, url string) {
    d.Resources = append(d.Resources, Resource{
        Filename: filename,
        Url:      url,
    })
}
func (d *Downloader) Download(resource Resource, progress *mpb.Progress) error {
    defer d.wg.Done()
    d.pool <- &resource
    finalPath := d.TargetDir + "/" + resource.Filename
    // 创建临时文件
    target, err := os.Create(finalPath + ".tmp")
    if err != nil {
        return err
    }
    // 开始下载
    req, err := http.NewRequest(http.MethodGet, resource.Url, nil)
    if err != nil {
        return err
    }
    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        target.Close()
        return err
    }
    defer resp.Body.Close()
    fileSize, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
    // 创建一个进度条
    bar := progress.AddBar(
        int64(fileSize),
        // 进度条前的修饰
        mpb.PrependDecorators(
            decor.CountersKibiByte("% .2f / % .2f"), // 已下载数量
            decor.Percentage(decor.WCSyncSpace),     // 进度百分比
        ),
        // 进度条后的修饰
        mpb.AppendDecorators(
            decor.EwmaETA(decor.ET_STYLE_GO, 90),
            decor.Name(" ] "),
            decor.EwmaSpeed(decor.UnitKiB, "% .2f", 60),
        ),
    )
    reader := bar.ProxyReader(resp.Body)
    defer reader.Close()
    // 将下载的文件流拷贝到临时文件
    if _, err := io.Copy(target, reader); err != nil {
        target.Close()
        return err
    }
    // 关闭临时并修改临时文件为最终文件
    target.Close()
    if err := os.Rename(finalPath+".tmp", finalPath); err != nil {
        return err
    }
    <-d.pool
    return nil
}
func (d *Downloader) Start() error {
    d.pool = make(chan *Resource, d.Concurrent)
    fmt.Println("开始下载,当前并发:", d.Concurrent)
    p := mpb.New(mpb.WithWaitGroup(d.wg))
    for _, resource := range d.Resources {
        d.wg.Add(1)
        go d.Download(resource, p)
    }
    p.Wait()
    d.wg.Wait()
    return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant