bytes.go 2.0 KB

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