Skip to content

Instantly share code, notes, and snippets.

@KonradIT
Created December 17, 2022 16:17
Show Gist options
  • Select an option

  • Save KonradIT/790c7db9b17ddc301e58d23b378e87b3 to your computer and use it in GitHub Desktop.

Select an option

Save KonradIT/790c7db9b17ddc301e58d23b378e87b3 to your computer and use it in GitHub Desktop.

Revisions

  1. KonradIT created this gist Dec 17, 2022.
    102 changes: 102 additions & 0 deletions download_concurrent.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,102 @@
    package main

    import (
    "io"
    "log"
    "net/http"
    "os"
    "path/filepath"
    "strconv"
    "sync"
    "time"

    "github.com/vbauerster/mpb/v8"
    "github.com/vbauerster/mpb/v8/decor"
    )

    const (
    FILE_1 = "http://172.23.120.51:8080/videos/DCIM/100GOPRO/GX010375.MP4"
    FILE_2 = "http://172.23.120.51:8080/videos/DCIM/100GOPRO/GOPR0377.JPG"
    FILE_3 = "http://172.23.120.51:8080/videos/DCIM/100GOPRO/G0010378.JPG"
    )

    var (
    FILES = []string{FILE_1, FILE_2, FILE_3}
    )

    func head(path string) (int, error) {

    client := &http.Client{}
    req, err := http.NewRequest("HEAD", path, nil)
    if err != nil {
    return 0, err
    }
    resp, err := client.Do(req)
    if err != nil {
    return 0, err
    }
    length, err := strconv.Atoi(resp.Header.Get("Content-Length"))
    if err != nil {
    return 0, err
    }
    return length, nil
    }

    func downloadFile(filePath string, bar *mpb.Bar) error {
    resp, err := http.Get(filePath)
    if err != nil {
    return err
    }
    defer resp.Body.Close()

    name := filepath.Base(filePath)

    file, err := os.Create(name)
    if err != nil {
    return err
    }
    defer file.Close()
    proxyReader := bar.ProxyReader(resp.Body)
    defer proxyReader.Close()

    _, err = io.Copy(file, proxyReader)
    if err != nil {
    return err
    }
    return nil
    }

    func main() {
    var wg sync.WaitGroup
    p := mpb.New(mpb.WithWaitGroup(&wg),
    mpb.WithWidth(60),
    mpb.WithRefreshRate(180*time.Millisecond))
    nfiles := len(FILES)

    for i := 0; i < nfiles; i++ {
    head, err := head(FILES[i])
    if err != nil {
    panic(err)
    }
    bar := p.AddBar(int64(head),
    mpb.PrependDecorators(
    decor.CountersKiloByte("% .2f / % .2f"),
    ),
    mpb.AppendDecorators(
    decor.OnComplete(
    decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WCSyncWidth), "✔️",
    ),
    ),
    )

    wg.Add(1)
    go func(current int) {
    defer wg.Done()
    err := downloadFile(FILES[current], bar)
    if err != nil {
    log.Fatal(err.Error())
    }
    }(i)
    }
    p.Wait()
    }