bytes.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package bytes
  2. import (
  3. "fmt"
  4. "regexp"
  5. "strconv"
  6. )
  7. type (
  8. // Bytes struct
  9. Bytes struct{}
  10. )
  11. const (
  12. _ = 1.0 << (10 * iota) // ignore first value by assigning to blank identifier
  13. KB
  14. MB
  15. GB
  16. TB
  17. PB
  18. EB
  19. )
  20. var (
  21. pattern = regexp.MustCompile(`(?i)^(-?\d+(?:\.\d+)?)([KMGTPE]B?|B?)$`)
  22. global = New()
  23. )
  24. // New creates a Bytes instance.
  25. func New() *Bytes {
  26. return &Bytes{}
  27. }
  28. // Format formats bytes integer to human readable string.
  29. // For example, 31323 bytes will return 30.59KB.
  30. func (*Bytes) Format(b int64) string {
  31. multiple := ""
  32. value := float64(b)
  33. switch {
  34. case b >= EB:
  35. value /= EB
  36. multiple = "EB"
  37. case b >= PB:
  38. value /= PB
  39. multiple = "PB"
  40. case b >= TB:
  41. value /= TB
  42. multiple = "TB"
  43. case b >= GB:
  44. value /= GB
  45. multiple = "GB"
  46. case b >= MB:
  47. value /= MB
  48. multiple = "MB"
  49. case b >= KB:
  50. value /= KB
  51. multiple = "KB"
  52. case b == 0:
  53. return "0"
  54. default:
  55. return strconv.FormatInt(b, 10) + "B"
  56. }
  57. return fmt.Sprintf("%.2f%s", value, multiple)
  58. }
  59. // Parse parses human readable bytes string to bytes integer.
  60. // For example, 6GB (6G is also valid) will return 6442450944.
  61. func (*Bytes) Parse(value string) (i int64, err error) {
  62. parts := pattern.FindStringSubmatch(value)
  63. if len(parts) < 3 {
  64. return 0, fmt.Errorf("error parsing value=%s", value)
  65. }
  66. bytesString := parts[1]
  67. multiple := parts[2]
  68. bytes, err := strconv.ParseFloat(bytesString, 64)
  69. if err != nil {
  70. return
  71. }
  72. switch multiple {
  73. default:
  74. return int64(bytes), nil
  75. case "K", "KB":
  76. return int64(bytes * KB), nil
  77. case "M", "MB":
  78. return int64(bytes * MB), nil
  79. case "G", "GB":
  80. return int64(bytes * GB), nil
  81. case "T", "TB":
  82. return int64(bytes * TB), nil
  83. case "P", "PB":
  84. return int64(bytes * PB), nil
  85. case "E", "EB":
  86. return int64(bytes * EB), nil
  87. }
  88. }
  89. // Format wraps global Bytes's Format function.
  90. func Format(b int64) string {
  91. return global.Format(b)
  92. }
  93. // Parse wraps global Bytes's Parse function.
  94. func Parse(val string) (int64, error) {
  95. return global.Parse(val)
  96. }