You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
3.5 KiB

4 years ago
4 years ago
  1. package utils
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/fsnotify/fsnotify"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. )
  10. //@author: [songzhibin97](https://github.com/songzhibin97)
  11. //@struct_name: Watch
  12. //@description: 监控对象
  13. type Watch struct {
  14. *fsnotify.Watcher
  15. }
  16. //@author: [songzhibin97](https://github.com/songzhibin97)
  17. //@function: NewWatch
  18. //@description: Watch的实例化方法
  19. //@return: *Watch
  20. func NewWatch() *Watch {
  21. obj, _ := fsnotify.NewWatcher()
  22. return &Watch{obj}
  23. }
  24. //@author: [songzhibin97](https://github.com/songzhibin97)
  25. //@object: w *Watch
  26. //@function: Watch
  27. //@description: 监控对象
  28. //@param: path string, t *T
  29. //@return: error
  30. func (w *Watch) Watch(path string, t *T) error {
  31. // 先转化为绝对路径
  32. path, err := filepath.Abs(path)
  33. if err != nil {
  34. return err
  35. }
  36. // 判断是单个文件还是目录文件
  37. fileInfo, err := os.Stat(path)
  38. if err != nil {
  39. return err
  40. }
  41. // 判断是否是目录 添加监控
  42. if fileInfo.IsDir() {
  43. // dir
  44. err = w.watchDir(path)
  45. } else {
  46. err = w.watchFile(path)
  47. }
  48. if err != nil {
  49. return err
  50. }
  51. c := make(chan error)
  52. // 启动监控
  53. go func() {
  54. for {
  55. select {
  56. case even, ok := <-w.Events:
  57. if !ok {
  58. // close
  59. fmt.Println("Errors close")
  60. c <- errors.New("errors close")
  61. return
  62. }
  63. // 判断事件
  64. switch {
  65. case even.Op&fsnotify.Create == fsnotify.Create:
  66. //这里获取新创建文件的信息,如果是目录,则加入监控中
  67. fmt.Println("创建文件 : ", even.Name)
  68. //t.AddTask()
  69. _ = w.Add(even.Name)
  70. case even.Op&fsnotify.Write == fsnotify.Write:
  71. fmt.Println("修改文件 : ", even.Name)
  72. w.addTask(t, even.Name)
  73. case even.Op&fsnotify.Remove == fsnotify.Remove || even.Op&fsnotify.Rename == fsnotify.Rename:
  74. fmt.Println("删除或重命名文件 : ", even.Name)
  75. _ = w.Remove(even.Name)
  76. w.addTask(t, even.Name)
  77. }
  78. case err = <-w.Errors:
  79. fmt.Println("even Error:", err)
  80. c <- err
  81. return
  82. }
  83. }
  84. }()
  85. return <-c
  86. }
  87. //@author: [songzhibin97](https://github.com/songzhibin97)
  88. //@object: w *Watch
  89. //@function: watchDir
  90. //@description: 处理监控目录
  91. //@param: path string
  92. //@return: error
  93. func (w *Watch) watchDir(path string) error {
  94. // 先将自己添加到监控
  95. err := w.Add(path)
  96. if err != nil {
  97. return err
  98. }
  99. fileSlice, err := ioutil.ReadDir(path)
  100. if err != nil {
  101. return err
  102. }
  103. for _, f := range fileSlice {
  104. fPath := filepath.Join(path, f.Name())
  105. if !f.IsDir() {
  106. // 判断是否可监控的文件
  107. if chickPower(fPath) {
  108. err = w.watchFile(fPath)
  109. if err != nil {
  110. return err
  111. }
  112. }
  113. } else {
  114. err := w.watchDir(fPath)
  115. if err != nil {
  116. return err
  117. }
  118. }
  119. }
  120. return err
  121. }
  122. //@author: [songzhibin97](https://github.com/songzhibin97)
  123. //@object: w *Watch
  124. //@function: watchDir
  125. //@description: 处理监控单文件
  126. //@param: path string
  127. //@return: error
  128. func (w *Watch) watchFile(path string) error {
  129. var err error
  130. if chickPower(path) {
  131. err = w.Add(path)
  132. }
  133. return err
  134. }
  135. //@author: [songzhibin97](https://github.com/songzhibin97)
  136. //@function: chickPower
  137. //@description: 判断是否在可控范围内
  138. //@param: path string
  139. //@return: error
  140. func chickPower(name string) bool {
  141. name = filepath.Ext(name)
  142. return name == ".go" || name == ".yaml"
  143. }
  144. //@author: [songzhibin97](https://github.com/songzhibin97)
  145. //@object: w *Watch
  146. //@function: addTask
  147. //@description: 偏函数 简化发送任务
  148. //@param: path string
  149. //@return: error
  150. func (w *Watch) addTask(t *T, name string) {
  151. if chickPower(name) {
  152. fmt.Println("Add Task->>>>>>")
  153. t.AddTask()
  154. }
  155. }