progressio
progressio copied to clipboard
Go library to get progress feedback from io.Reader and io.Writer objects
progressio
Library to get progress feedback from io.Reader and io.Writer objects
To install, run go get github.com/bartmeuris/progressio
About
This package was created since most progress packages out-there seem to directly want to output stuff to a console mixing UI and work logic, work in a non-Go way (callback functions), or can only be used for specific scenario's like file downloads from the web.
This package provides wrappers around standard io.Reader and io.Writer objects which send back a progressio.Progress struct over a channel, so anything that uses standard io.Reader/io.Writer objects can give you progress feedback. It attempts to do all the heavy lifting for you:
- updates are throttled to 1 per 100ms (10 per second)
- Precalculates things (if possible) like:
- Speed in bytes/sec of the last few operations
- Average speed in bytes/sec since the start of the operation
- Remaining time
- Percentage
Some of these statistics are not available if the size was not specified up front.
Progress object
Layout
type Progress struct {
Transferred int64 // Transferred data in bytes
TotalSize int64 // Total size of the transfer in bytes. <= 0 if size is unknown.
Percent float64 // If the size is known, the progress of the transfer in %
SpeedAvg int64 // Bytes/sec average over the entire transfer
Speed int64 // Bytes/sec of the last few reads/writes
Remaining time.Duration // Estimated time remaining, only available if the size is known.
StartTime time.Time // When the transfer was started
StopTime time.Time // only specified when the transfer is completed: when the transfer was stopped
}
Functions
The progressio.Progress object has at the moment only one function, the
String() function to return the string
representation of the object.
Example
import (
"io"
"github.com/bartmeuris/progressio"
)
// io.Copy wrapper to specify the size and show copy progress.
func copyProgress(w io.Writer, r io.Reader, size int64) (written int64, err error) {
// Wrap your io.Writer:
pw, ch := progressio.NewProgressWriter(w, size)
defer pw.Close()
// Launch a Go-Routine reading from the progress channel
go func() {
for p := range ch {
fmt.Printf("\rProgress: %s", p.String())
}
fmt.Printf("\nDone\n")
}
// Copy the data from the reader to the new writer
return io.Copy(pw, r)
}
TODO
- Add tests
- Clean up documentation
- Document byte/duration formatters
- Extract byte/duration formatters and place in separate library (?)