Skip to content

Instantly share code, notes, and snippets.

@bayucandra
Forked from albulescu/download.go
Created April 7, 2022 09:52
Show Gist options
  • Save bayucandra/d08c49db6ec2afeb0eac031e5c8bf30d to your computer and use it in GitHub Desktop.
Save bayucandra/d08c49db6ec2afeb0eac031e5c8bf30d to your computer and use it in GitHub Desktop.
golang download file with progress
package main
/**
* @website http://albulescu.ro
* @author Cosmin Albulescu <cosmin@albulescu.ro>
*/
import (
"bytes"
"fmt"
"io"
"log"
"net/http"
"os"
"path"
"strconv"
"time"
)
func PrintDownloadPercent(done chan int64, path string, total int64) {
var stop bool = false
for {
select {
case <-done:
stop = true
default:
file, err := os.Open(path)
if err != nil {
log.Fatal(err)
}
fi, err := file.Stat()
if err != nil {
log.Fatal(err)
}
size := fi.Size()
if size == 0 {
size = 1
}
var percent float64 = float64(size) / float64(total) * 100
fmt.Printf("%.0f", percent)
fmt.Println("%")
}
if stop {
break
}
time.Sleep(time.Second)
}
}
func DownloadFile(url string, dest string) {
file := path.Base(url)
log.Printf("Downloading file %s from %s\n", file, url)
var path bytes.Buffer
path.WriteString(dest)
path.WriteString("/")
path.WriteString(file)
start := time.Now()
out, err := os.Create(path.String())
if err != nil {
fmt.Println(path.String())
panic(err)
}
defer out.Close()
headResp, err := http.Head(url)
if err != nil {
panic(err)
}
defer headResp.Body.Close()
size, err := strconv.Atoi(headResp.Header.Get("Content-Length"))
if err != nil {
panic(err)
}
done := make(chan int64)
go PrintDownloadPercent(done, path.String(), int64(size))
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
n, err := io.Copy(out, resp.Body)
if err != nil {
panic(err)
}
done <- n
elapsed := time.Since(start)
log.Printf("Download completed in %s", elapsed)
}
func main() {
DownloadFile("https://wordpress.org/wordpress-4.4.2.zip","./")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment