package main /** * @website http://albulescu.ro * @author Cosmin Albulescu */ 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","./") }