github.com/iikira/iikira-go-utils@v0.0.0-20230610031953-f2cb11cde33a/utils/converter/size.go (about)

     1  package converter
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  const (
    11  	// B byte
    12  	B = (int64)(1 << (10 * iota))
    13  	// KB kilobyte
    14  	KB
    15  	// MB megabyte
    16  	MB
    17  	// GB gigabyte
    18  	GB
    19  	// TB terabyte
    20  	TB
    21  	// PB petabyte
    22  	PB
    23  )
    24  
    25  // ConvertFileSize 文件大小格式化输出
    26  func ConvertFileSize(size int64, precision ...int) string {
    27  	pint := "6"
    28  	if len(precision) == 1 {
    29  		pint = fmt.Sprint(precision[0])
    30  	}
    31  	if size < 0 {
    32  		return "0B"
    33  	}
    34  	if size < KB {
    35  		return fmt.Sprintf("%dB", size)
    36  	}
    37  	if size < MB {
    38  		return fmt.Sprintf("%."+pint+"fKB", float64(size)/float64(KB))
    39  	}
    40  	if size < GB {
    41  		return fmt.Sprintf("%."+pint+"fMB", float64(size)/float64(MB))
    42  	}
    43  	if size < TB {
    44  		return fmt.Sprintf("%."+pint+"fGB", float64(size)/float64(GB))
    45  	}
    46  	if size < PB {
    47  		return fmt.Sprintf("%."+pint+"fTB", float64(size)/float64(TB))
    48  	}
    49  	return fmt.Sprintf("%."+pint+"fPB", float64(size)/float64(PB))
    50  }
    51  
    52  // ParseFileSizeStr 将文件大小字符串转换成字节数
    53  func ParseFileSizeStr(ss string) (size int64, err error) {
    54  	if ss == "" {
    55  		err = errors.New("converter: size is empty")
    56  		return
    57  	}
    58  	if !(ss[0] == '.' || '0' <= ss[0] && ss[0] <= '9') {
    59  		err = errors.New("converter: invalid size: " + ss)
    60  		return
    61  	}
    62  
    63  	var i int
    64  	for i = range ss[1:] {
    65  		i++
    66  		if ss[i] == '.' || ('0' <= ss[i] && ss[i] <= '9') {
    67  			// 属于数字
    68  			continue
    69  		}
    70  		break
    71  	}
    72  	if ss[i] == '.' || ('0' <= ss[i] && ss[i] <= '9') { // 最后一个分隔符是否为数字
    73  		i++
    74  	}
    75  
    76  	var (
    77  		sizeStr      = ss[:i] // 数字部分
    78  		unitStr      = ss[i:] // 单位部分
    79  		sizeFloat, _ = strconv.ParseFloat(sizeStr, 10)
    80  	)
    81  	switch strings.ToUpper(unitStr) {
    82  	case "", "B":
    83  		size = int64(sizeFloat)
    84  	case "K", "KB":
    85  		size = int64(sizeFloat * float64(KB))
    86  	case "M", "MB":
    87  		size = int64(sizeFloat * float64(MB))
    88  	case "G", "GB":
    89  		size = int64(sizeFloat * float64(GB))
    90  	case "T", "TB":
    91  		size = int64(sizeFloat * float64(TB))
    92  	case "P", "PB":
    93  		size = int64(sizeFloat * float64(PB))
    94  	default:
    95  		err = errors.New("converter: invalid unit " + unitStr)
    96  	}
    97  	return
    98  }