package main import ( "fmt" "strings" "os" "io" "net/http" "path/filepath" ) // WriteCounter counts the number of bytes written to it type WriteCounter struct { Filepath 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() { // clear the line by using a character return to go back to the start of the // line and remove the remaining characters fmt.Printf("\r%s", strings.Repeat(" ", 35)) fmt.Printf("\r[%s]... %d bytes complete", wc.Filepath, wc.Total) } func downloadFile(path string, url string) error { // make sure dir exists os.MkdirAll(filepath.Dir(path), 0777) // create .part file output, err := os.Create(path + ".part") if err != nil { return err } defer output.Close() // get data response, err := http.Get(url) if err != nil { return err } defer response.Body.Close() // create progress reporter counter := &WriteCounter{path, 0} _, err = io.Copy(output, io.TeeReader(response.Body, counter)) if err != nil { return err } fmt.Printf("\n") //fmt.Printf("\r%s", strings.Repeat(" ", 40)) os.Rename(path + ".part", path) //fmt.Printf("\r[%s] complete\n", path) return nil }