github.com/qiniu/go-sdk/v7@v7.27.0/storage/recorder.go (about) 1 package storage 2 3 import ( 4 "bytes" 5 "crypto/sha1" 6 "io" 7 "os" 8 "path/filepath" 9 "strconv" 10 "strings" 11 "time" 12 ) 13 14 type Recorder interface { 15 // 新建或更新文件分片上传的进度 16 Set(key string, data []byte) error 17 18 // 获取文件分片上传的进度信息 19 Get(key string) ([]byte, error) 20 21 // 删除文件分片上传的进度文件 22 Delete(key string) error 23 24 // 根据给定的文件信息生成持久化纪录的 key 25 GenerateRecorderKey(keyInfos []string, sourceFileInfo os.FileInfo) string 26 } 27 28 type FileRecorder struct { 29 directoryPath string 30 } 31 32 func NewFileRecorder(directoryPath string) (fileRecorder *FileRecorder, err error) { 33 err = os.MkdirAll(directoryPath, 0700) 34 if err != nil { 35 return 36 } 37 fileRecorder = &FileRecorder{directoryPath: directoryPath} 38 return 39 } 40 41 func (fileRecorder *FileRecorder) Set(key string, data []byte) error { 42 path := filepath.Join(fileRecorder.directoryPath, key) 43 file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 44 if err != nil { 45 return err 46 } 47 defer file.Close() 48 _, err = io.Copy(file, bytes.NewReader(data)) 49 return err 50 } 51 52 func (fileRecorder *FileRecorder) Get(key string) ([]byte, error) { 53 path := filepath.Join(fileRecorder.directoryPath, key) 54 file, err := os.Open(path) 55 if err != nil { 56 return nil, err 57 } 58 defer file.Close() 59 60 fileInfo, err := file.Stat() 61 if err != nil { 62 return nil, err 63 } 64 if isRecorderFileOutOfDate(fileInfo) { 65 err = fileRecorder.Delete(key) 66 return nil, err 67 } 68 69 buffer := new(bytes.Buffer) 70 _, err = io.Copy(buffer, file) 71 return buffer.Bytes(), err 72 } 73 74 func (fileRecorder *FileRecorder) Delete(key string) error { 75 path := filepath.Join(fileRecorder.directoryPath, key) 76 return os.Remove(path) 77 } 78 79 func (fileRecorder *FileRecorder) GenerateRecorderKey(keyInfos []string, sourceFileInfo os.FileInfo) string { 80 const delimiter = "*:|>?^ \b" 81 buffer := new(bytes.Buffer) 82 for _, keyInfo := range keyInfos { 83 buffer.WriteString(keyInfo) 84 buffer.WriteString(delimiter) 85 } 86 buffer.WriteString(sourceFileInfo.ModTime().String()) 87 return hashRecorderKey(buffer.Bytes()) 88 } 89 90 func isRecorderFileOutOfDate(fileInfo os.FileInfo) bool { 91 return fileInfo.ModTime().Add(24 * 5 * time.Hour).Before(time.Now()) 92 } 93 94 func hashRecorderKey(base []byte) string { 95 sha1edBase := sha1.Sum(base) 96 97 var stringBuilder strings.Builder 98 for i := 0; i < len(sha1edBase); i++ { 99 b := (int64(sha1edBase[i]) & 0xff) + 0x100 100 stringBuilder.WriteString(strconv.FormatInt(b, 16)[1:]) 101 } 102 return stringBuilder.String() 103 }