utils.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package oss
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "os"
  8. "os/exec"
  9. "runtime"
  10. "time"
  11. )
  12. // Get User Agent
  13. // Go sdk相关信息,包括sdk版本,操作系统类型,GO版本
  14. var userAgent = func() string {
  15. sys := getSysInfo()
  16. return fmt.Sprintf("aliyun-sdk-go/%s (%s/%s/%s;%s)", Version, sys.name,
  17. sys.release, sys.machine, runtime.Version())
  18. }()
  19. type sysInfo struct {
  20. name string // 操作系统名称windows/Linux
  21. release string // 操作系统版本 2.6.32-220.23.2.ali1089.el5.x86_64等
  22. machine string // 机器类型amd64/x86_64
  23. }
  24. // Get system info
  25. // 获取操作系统信息、机器类型
  26. func getSysInfo() sysInfo {
  27. name := runtime.GOOS
  28. release := "-"
  29. machine := runtime.GOARCH
  30. if out, err := exec.Command("uname", "-s").CombinedOutput(); err == nil {
  31. name = string(bytes.TrimSpace(out))
  32. }
  33. if out, err := exec.Command("uname", "-r").CombinedOutput(); err == nil {
  34. release = string(bytes.TrimSpace(out))
  35. }
  36. if out, err := exec.Command("uname", "-m").CombinedOutput(); err == nil {
  37. machine = string(bytes.TrimSpace(out))
  38. }
  39. return sysInfo{name: name, release: release, machine: machine}
  40. }
  41. // GetNowSec returns Unix time, the number of seconds elapsed since January 1, 1970 UTC.
  42. // 获取当前时间,从UTC开始的秒数。
  43. func GetNowSec() int64 {
  44. return time.Now().Unix()
  45. }
  46. // GetNowNanoSec returns t as a Unix time, the number of nanoseconds elapsed
  47. // since January 1, 1970 UTC. The result is undefined if the Unix time
  48. // in nanoseconds cannot be represented by an int64. Note that this
  49. // means the result of calling UnixNano on the zero Time is undefined.
  50. // 获取当前时间,从UTC开始的纳秒。
  51. func GetNowNanoSec() int64 {
  52. return time.Now().UnixNano()
  53. }
  54. // GetNowGMT 获取当前时间,格式形如"Mon, 02 Jan 2006 15:04:05 GMT",HTTP中使用的时间格式
  55. func GetNowGMT() string {
  56. return time.Now().UTC().Format(http.TimeFormat)
  57. }
  58. // FileChunk 文件片定义
  59. type FileChunk struct {
  60. Number int // 块序号
  61. Offset int64 // 块在文件中的偏移量
  62. Size int64 // 块大小
  63. }
  64. // SplitFileByPartNum Split big file to part by the num of part
  65. // 按指定的块数分割文件。返回值FileChunk为分割结果,error为nil时有效。
  66. func SplitFileByPartNum(fileName string, chunkNum int) ([]FileChunk, error) {
  67. if chunkNum <= 0 || chunkNum > 10000 {
  68. return nil, errors.New("chunkNum invalid")
  69. }
  70. file, err := os.Open(fileName)
  71. if err != nil {
  72. return nil, err
  73. }
  74. defer file.Close()
  75. stat, err := file.Stat()
  76. if err != nil {
  77. return nil, err
  78. }
  79. if int64(chunkNum) > stat.Size() {
  80. return nil, errors.New("oss: chunkNum invalid")
  81. }
  82. var chunks []FileChunk
  83. var chunk = FileChunk{}
  84. var chunkN = (int64)(chunkNum)
  85. for i := int64(0); i < chunkN; i++ {
  86. chunk.Number = int(i + 1)
  87. chunk.Offset = i * (stat.Size() / chunkN)
  88. if i == chunkN-1 {
  89. chunk.Size = stat.Size()/chunkN + stat.Size()%chunkN
  90. } else {
  91. chunk.Size = stat.Size() / chunkN
  92. }
  93. chunks = append(chunks, chunk)
  94. }
  95. return chunks, nil
  96. }
  97. // SplitFileByPartSize Split big file to part by the size of part
  98. // 按块大小分割文件。返回值FileChunk为分割结果,error为nil时有效。
  99. func SplitFileByPartSize(fileName string, chunkSize int64) ([]FileChunk, error) {
  100. if chunkSize <= 0 {
  101. return nil, errors.New("chunkSize invalid")
  102. }
  103. file, err := os.Open(fileName)
  104. if err != nil {
  105. return nil, err
  106. }
  107. defer file.Close()
  108. stat, err := file.Stat()
  109. if err != nil {
  110. return nil, err
  111. }
  112. var chunkN = stat.Size() / chunkSize
  113. if chunkN >= 10000 {
  114. return nil, errors.New("Too many parts, please increase part size.")
  115. }
  116. var chunks []FileChunk
  117. var chunk = FileChunk{}
  118. for i := int64(0); i < chunkN; i++ {
  119. chunk.Number = int(i + 1)
  120. chunk.Offset = i * chunkSize
  121. chunk.Size = chunkSize
  122. chunks = append(chunks, chunk)
  123. }
  124. if stat.Size()%chunkSize > 0 {
  125. chunk.Number = len(chunks) + 1
  126. chunk.Offset = int64(len(chunks)) * chunkSize
  127. chunk.Size = stat.Size() % chunkSize
  128. chunks = append(chunks, chunk)
  129. }
  130. return chunks, nil
  131. }
  132. // GetPartEnd 计算结束位置
  133. func GetPartEnd(begin int64, total int64, per int64) int64 {
  134. if begin+per > total {
  135. return total - 1
  136. }
  137. return begin + per - 1
  138. }