GO监控linux下目录操作

对于linux有个inotify机制想必各linuxer都是知道的,最近在学习GO语言想使用go实现inotify-toos的一些功能,比如发现指定目录下的新建文件,关闭文件等操作。起初使用github上fsnotify/fsnotify发现无法监控到write_close状态,经过一些时间的搜寻发现ericbrisrubio/fsnotify支持linux原生的inotify机制。下面是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main

import (
"fmt"
"io/ioutil"
"os"

"github.com/ericbrisrubio/fsnotify"
)

func main() {
filename := os.Args[1]
go watchDir(filename)

select {}
}


/*
将监控主函数
*/
func watchDir(filename string) {
watch, _ := fsnotify.NewWatcher()
defer watch.Close()

err := watch.Watch(filename)
if err != nil {
fmt.Errorf("监听目录失败:%v", err.Error())
}

//把指定目录下的所有目录都加入监控
for _, k := range listDir(filename) {
watch.Watch(fmt.Sprintf("%s/%s", filename, k))
}

for {
select {
case event := <-watch.Event:
{
if event.IsCreate() {
fmt.Println(event.Name, " create")
//发现创建的文件是目录,则加入监控
if isDir(event.Name) {
watch.Watch(event.Name)
continue
}
}
//发现文件被写入关闭则写入消息队列
if event.IsCloseWrite() {
fmt.Println(event.Name, " Close write")
}
}
case err := <-watch.Error:
{
fmt.Errorf("Err:%v", err)
continue
}
}
}
}

/*
检查是否是目录
*/
func isDir(path string) bool {
stat, err := os.Stat(path)
if err != nil {
fmt.Errorf("%v", err.Error())
return false
}
return stat.IsDir()
}

/*
递归列出所有目录
*/
func listDir(path string) []string {
var dirlist []string
fileList, err := ioutil.ReadDir(path)
if err != nil {
fmt.Errorf("list %s err:%v", path, err.Error())
return nil
}
for _, fileName := range fileList {
if fileName.IsDir() {
dirlist = append(dirlist, fmt.Sprintf("%s", fileName.Name()))
for _, k := range listDir(fmt.Sprintf("%s/%s", path, fileName.Name())) {
dirlist = append(dirlist, fmt.Sprintf("%s/%s", fileName.Name(), k))
}
}
}
return dirlist
}

0%