package main import ( "fmt" "io" "os" "path/filepath" "regexp" "sparrow/pkg/rpcs" "sparrow/pkg/server" "sparrow/pkg/utils" "sync" "time" ) const checkTimeOut = 30 * time.Minute // FileAccess RPC服务 type FileAccess struct { mu sync.RWMutex tempFiles map[string]*tempFile } // 代表一个临时文件 type tempFile struct { //文件路径 fileName string //创建时间 createTime time.Time } // NewFileAccess create a FileAccessor instance func NewFileAccess() *FileAccess { return &FileAccess{ tempFiles: make(map[string]*tempFile), } } // TODO: 临时解决文案,下个版本把文件信息写到redis中,利用redis的pub/sub机制,自动清理文件 func (f *FileAccess) checker() { server.Log.Info("开始文件过期检测") for { for k, v := range f.tempFiles { if time.Now().Sub(v.createTime) > checkTimeOut { //delete file f.mu.Lock() delete(f.tempFiles, k) f.mu.Unlock() err := os.Remove(v.fileName) if err != nil { server.Log.Errorf("自动清理文件失败:%v", err) } } } time.Sleep(30 * time.Minute) } } // MoveFile move a file to new path // source:http://192.168.175.60:9000/upload/tmp/2c9d7d85-2266-450a-9d47-28e67703d818.jpeg func (f *FileAccess) MoveFile(args *rpcs.ArgsMoveFile, reply *rpcs.ReplyMoveFile) error { // check source file reg := regexp.MustCompile(`tmp/\$*.*`) src := reg.FindString(args.Source) fileName := filepath.Base(src) server.Log.Debug(src) src = *conStaticPath + "/" + src b, err := utils.Exists(src) if err != nil { server.Log.Error(err) return err } if b { // copy file sourceFileStat, err := os.Stat(src) if err != nil { return err } if !sourceFileStat.Mode().IsRegular() { return fmt.Errorf("%s is not a regular file", src) } source, err := os.Open(src) if err != nil { return err } defer source.Close() dst := *conStaticPath + "/" + args.Target + "/" + fileName utils.CreateIfNotExist(dst) destination, err := os.Create(dst) if err != nil { return err } defer destination.Close() io.Copy(destination, source) fpath := fmt.Sprintf("http://%s/%s/%s/%s", server.GetHTTPHost(), *conStaticPath, args.Target, fileName) if *conDomain != "" { fpath = fmt.Sprintf("http://%s/%s/%s/%s", *conDomain, *conStaticPath, args.Target, fileName) } reply.FilePath = fpath //delete src os.Remove(src) return nil } return nil }