fileaccess.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package main
  2. import (
  3. "fmt"
  4. "io"
  5. "os"
  6. "path/filepath"
  7. "regexp"
  8. "sparrow/pkg/rpcs"
  9. "sparrow/pkg/server"
  10. "sparrow/pkg/utils"
  11. "sync"
  12. "time"
  13. )
  14. const checkTimeOut = 30 * time.Minute
  15. // FileAccess RPC服务
  16. type FileAccess struct {
  17. mu sync.RWMutex
  18. tempFiles map[string]*tempFile
  19. }
  20. // 代表一个临时文件
  21. type tempFile struct {
  22. //文件路径
  23. fileName string
  24. //创建时间
  25. createTime time.Time
  26. }
  27. // NewFileAccess create a FileAccessor instance
  28. func NewFileAccess() *FileAccess {
  29. return &FileAccess{
  30. tempFiles: make(map[string]*tempFile),
  31. }
  32. }
  33. // TODO: 临时解决文案,下个版本把文件信息写到redis中,利用redis的pub/sub机制,自动清理文件
  34. func (f *FileAccess) checker() {
  35. server.Log.Info("开始文件过期检测")
  36. for {
  37. for k, v := range f.tempFiles {
  38. if time.Now().Sub(v.createTime) > checkTimeOut {
  39. //delete file
  40. f.mu.Lock()
  41. delete(f.tempFiles, k)
  42. f.mu.Unlock()
  43. err := os.Remove(v.fileName)
  44. if err != nil {
  45. server.Log.Errorf("自动清理文件失败:%v", err)
  46. }
  47. }
  48. }
  49. time.Sleep(30 * time.Minute)
  50. }
  51. }
  52. // MoveFile move a file to new path
  53. // source:http://192.168.175.60:9000/upload/tmp/2c9d7d85-2266-450a-9d47-28e67703d818.jpeg
  54. func (f *FileAccess) MoveFile(args *rpcs.ArgsMoveFile, reply *rpcs.ReplyMoveFile) error {
  55. // check source file
  56. reg := regexp.MustCompile(`tmp/\$*.*`)
  57. src := reg.FindString(args.Source)
  58. fileName := filepath.Base(src)
  59. server.Log.Debug(src)
  60. src = *conStaticPath + "/" + src
  61. b, err := utils.Exists(src)
  62. if err != nil {
  63. server.Log.Error(err)
  64. return err
  65. }
  66. if b {
  67. // copy file
  68. sourceFileStat, err := os.Stat(src)
  69. if err != nil {
  70. return err
  71. }
  72. if !sourceFileStat.Mode().IsRegular() {
  73. return fmt.Errorf("%s is not a regular file", src)
  74. }
  75. source, err := os.Open(src)
  76. if err != nil {
  77. return err
  78. }
  79. defer source.Close()
  80. dst := *conStaticPath + "/" + args.Target + "/" + fileName
  81. utils.CreateIfNotExist(dst)
  82. destination, err := os.Create(dst)
  83. if err != nil {
  84. return err
  85. }
  86. defer destination.Close()
  87. io.Copy(destination, source)
  88. fpath := fmt.Sprintf("http://%s/%s/%s/%s", server.GetHTTPHost(), *conStaticPath, args.Target, fileName)
  89. if *conDomain != "" {
  90. fpath = fmt.Sprintf("http://%s/%s/%s/%s", *conDomain, *conStaticPath, args.Target, fileName)
  91. }
  92. reply.FilePath = fpath
  93. //delete src
  94. os.Remove(src)
  95. return nil
  96. }
  97. return nil
  98. }