file.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. package cache
  2. import (
  3. "crypto/md5"
  4. "fmt"
  5. "os"
  6. "sync"
  7. "time"
  8. )
  9. type FileCache struct {
  10. mu sync.Mutex
  11. locks map[string]*sync.Mutex
  12. Dir string
  13. }
  14. func (fc *FileCache) getLock(key string) *sync.Mutex {
  15. fc.mu.Lock()
  16. defer fc.mu.Unlock()
  17. if fc.locks == nil {
  18. fc.locks = make(map[string]*sync.Mutex)
  19. }
  20. if _, ok := fc.locks[key]; !ok {
  21. fc.locks[key] = new(sync.Mutex)
  22. }
  23. return fc.locks[key]
  24. }
  25. func (c *FileCache) Get(key string, value interface{}) error {
  26. data, _ := c.getValue(key)
  27. err := DecodeValue(data, value)
  28. return err
  29. }
  30. // 获取值,如果文件不存在或者过期,返回空,过滤掉错误
  31. func (c *FileCache) getValue(key string) (string, error) {
  32. f := c.fileName(key)
  33. fileInfo, err := os.Stat(f)
  34. if err != nil {
  35. //文件不存在
  36. return "", nil
  37. }
  38. difT := time.Now().Sub(fileInfo.ModTime())
  39. if difT >= 0 {
  40. os.Remove(f)
  41. return "", nil
  42. }
  43. data, err := os.ReadFile(f)
  44. if err != nil {
  45. return "", nil
  46. }
  47. return string(data), nil
  48. }
  49. // 保存值
  50. func (c *FileCache) saveValue(key string, value string, exp int) error {
  51. f := c.fileName(key)
  52. lock := c.getLock(f)
  53. lock.Lock()
  54. defer lock.Unlock()
  55. err := os.WriteFile(f, ([]byte)(value), 0644)
  56. if err != nil {
  57. return err
  58. }
  59. if exp <= 0 {
  60. exp = MaxTimeOut
  61. }
  62. expFromNow := time.Now().Add(time.Duration(exp) * time.Second)
  63. err = os.Chtimes(f, expFromNow, expFromNow)
  64. return err
  65. }
  66. func (c *FileCache) Set(key string, value interface{}, exp int) error {
  67. str, err := EncodeValue(value)
  68. if err != nil {
  69. return err
  70. }
  71. err = c.saveValue(key, str, exp)
  72. return err
  73. }
  74. func (c *FileCache) SetDir(path string) {
  75. c.Dir = path
  76. }
  77. func (c *FileCache) fileName(key string) string {
  78. f := c.Dir + string(os.PathSeparator) + fmt.Sprintf("%x", md5.Sum([]byte(key)))
  79. return f
  80. }
  81. func (c *FileCache) Gc() error {
  82. //检查文件过期时间,并删除
  83. return nil
  84. }
  85. func NewFileCache() *FileCache {
  86. return &FileCache{
  87. locks: make(map[string]*sync.Mutex),
  88. Dir: os.TempDir(),
  89. }
  90. }