/datasize

Golang helpers for data sizes (kilobytes, petabytes), human readable sizes, parsing

Primary LanguageGoMIT LicenseMIT

datasize Build Status

Golang helpers for data sizes

Constants

Just like time package provides time.Second, time.Day constants datasize provides:

  • datasize.B 1 byte
  • datasize.KB 1 kilobyte
  • datasize.MB 1 megabyte
  • datasize.GB 1 gigabyte
  • datasize.TB 1 terabyte
  • datasize.PB 1 petabyte
  • datasize.EB 1 exabyte

Helpers

Just like time package provides duration.Nanoseconds() uint64 , duration.Hours() float64 helpers datasize has

  • ByteSize.Bytes() uint64
  • ByteSize.Kilobytes() float4
  • ByteSize.Megabytes() float64
  • ByteSize.Gigabytes() float64
  • ByteSize.Terabytes() float64
  • ByteSize.Petebytes() float64
  • ByteSize.Exabytes() float64

Warning: see limitations at the end of this document about a possible precission loss

Parsing strings

datasize.ByteSize implements TextUnmarshaler interface and will automatically parse human readable strings into correct values where it is used:

  • "10 MB" -> 10* datasize.MB
  • "10240 g" -> 10 * datasize.TB
  • "2000" -> 2000 * datasize.B
  • "1tB" -> datasize.TB
  • "5 peta" -> 5 * datasize.PB
  • "28 kilobytes" -> 28 * datasize.KB
  • "1 gigabyte" -> 1 * datasize.GB

You can also do it manually:

var v datasize.ByteSize
err := v.UnmarshalText([]byte("100 mb"))

Printing

Bytesize.String() uses largest unit allowing an integer value: * (102400 * datasize.MB).String() -> "100GB" * (datasize.MB + datasize.KB).String() -> "1025KB"

Use %d format string to get value in bytes without a unit

JSON and other encoding

Both TextMarshaler and TextUnmarshaler interfaces are implemented - JSON will just work. Other encoders will work provided they use those interfaces.

Human readable

ByteSize.HumanReadable() or ByteSize.HR() returns a string with 1-3 digits, followed by 1 decimal place, a space and unit big enough to get 1-3 digits

* `(102400 * datasize.MB).String()` -> `"100.0 GB"`
* `(datasize.MB + 512 * datasize.KB).String()` -> `"1.5 MB"`

Limitations

  • The underlying data type for data.ByteSize is uint64, so values outside of 0 to 2^64-1 range will overflow
  • size helper functions (like ByteSize.Kilobytes()) return float64, which can't represent all possible values of uint64 accurately:
    • if the returned value is supposed to have no fraction (ie (10 * datasize.MB).Kilobytes()) accuracy loss happens when value is more than 2^53 larger than unit: .Kilobytes() over 8 petabytes, .Megabytes() over 8 exabytes
    • if the returned value is supposed to have a fraction (ie (datasize.PB + datasize.B).Megabytes()) in addition to the above note accuracy loss may occur in fractional part too - larger integer part leaves fewer bytes to store fractional part, the smaller the remainder vs unit the move bytes are required to store the fractional part
  • Parsing a string with Mb, Tb, etc units will return a syntax error, because capital followed by lower case is commonly used for bits, not bytes
  • Parsing a string with value exceeding 2^64-1 bytes will return 2^64-1 and an out of range error