Dalam golang, anda boleh menggunakan fsnotify untuk melaksanakan pemantauan fail. fsnotify ialah alat pemantauan sistem fail merentas platform dalam bahasa Go, yang melaksanakan antara muka pemantauan masa nyata berasaskan saluran, golang boleh memantau fail melalui fsnotify dan memulakan semula program melalui perubahan fail.
Persekitaran pengendalian tutorial ini: sistem Windows 10, GO versi 1.18, komputer Dell G3.
Dalam golang, anda boleh menggunakan fsnotify untuk melaksanakan pemantauan fail.
golang memantau fail melalui fsnotify dan memulakan semula program melalui perubahan fail.
Alat pemantauan sistem fail merentas platform bahasa Go - fsnotify
Dalam kernel Linux, Inotify ialah alat yang digunakan untuk memberitahu pengguna Mekanisme perubahan sistem fail program spatial. Ia memantau perubahan sistem fail, seperti penciptaan fail, pengubahsuaian, pemadaman, dsb., dan boleh memberitahu aplikasi tentang peristiwa yang sepadan.
Inotify boleh memantau kedua-dua fail dan direktori. Apabila memantau direktori, ia boleh memantau direktori dan setiap subdirektori dan fail dalam direktori pada masa yang sama. Syscall perpustakaan standard Golang melaksanakan mekanisme ini.
Untuk mengembangkan dan mengabstrakkan lagi, pakej github.com/fsnotify/fsnotify melaksanakan antara muka pemantauan masa nyata berasaskan saluran dan merentas platform.
Penggunaan alat fsnotify
1 Muat turun pakej yang kami perlukan
go get github.com/fsnotify/fsnotify
Salin selepas log masuk
2 fail
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
|
package main;
import (
"github.com/fsnotify/fsnotify"
"log"
"fmt"
)
func main() {
watch, err := fsnotify.NewWatcher();
if err != nil {
log.Fatal(err);
}
defer watch.Close();
err = watch.Add( "./tmp" );
if err != nil {
log.Fatal(err);
}
go func() {
for {
select {
case ev :=
{
if ev.Op&fsnotify.Create == fsnotify.Create {
log.Println( "创建文件 : " , ev.Name);
}
if ev.Op&fsnotify.Write == fsnotify.Write {
log.Println( "写入文件 : " , ev.Name);
}
if ev.Op&fsnotify.Remove == fsnotify.Remove {
log.Println( "删除文件 : " , ev.Name);
}
if ev.Op&fsnotify.Rename == fsnotify.Rename {
log.Println( "重命名文件 : " , ev.Name);
}
if ev.Op&fsnotify.Chmod == fsnotify.Chmod {
log.Println( "修改权限 : " , ev.Name);
}
}
case err :=
{
log.Println( "error : " , err);
return ;
}
}
}
}();
select {};
}
|
Keputusan ujian adalah seperti berikut:
Semua operasi kami dalam direktori tmp telah ditangkap, tetapi terdapat masalah dengan fsnotify. Ia tidak dapat membantu kami menangkap subdirektori secara rekursif . Acara operasi direktori Sun Tzu perlu dilaksanakan oleh kami sendiri.
Masalah lain ialah apabila kami mengubah suai nama folder, acara.Nama dalam fsnotify masih merupakan nama fail asal Ini memerlukan kami mengalih keluar pemantauan sebelumnya dalam acara menamakan semula, dan kemudian menambah Pemantauan baharu.
diubah suai seperti berikut:
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
|
package main;
import (
"github.com/fsnotify/fsnotify"
"fmt"
"path/filepath"
"os"
)
type Watch struct {
watch *fsnotify.Watcher;
}
func (w *Watch) watchDir(dir string) {
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
path, err := filepath.Abs(path);
if err != nil {
return err;
}
err = w.watch.Add(path);
if err != nil {
return err;
}
fmt.Println( "监控 : " , path);
}
return nil;
});
go func() {
for {
select {
case ev :=
{
if ev.Op&fsnotify.Create == fsnotify.Create {
fmt.Println( "创建文件 : " , ev.Name);
fi, err := os.Stat(ev.Name);
if err == nil && fi.IsDir() {
w.watch.Add(ev.Name);
fmt.Println( "添加监控 : " , ev.Name);
}
}
if ev.Op&fsnotify.Write == fsnotify.Write {
fmt.Println( "写入文件 : " , ev.Name);
}
if ev.Op&fsnotify.Remove == fsnotify.Remove {
fmt.Println( "删除文件 : " , ev.Name);
fi, err := os.Stat(ev.Name);
if err == nil && fi.IsDir() {
w.watch.Remove(ev.Name);
fmt.Println( "删除监控 : " , ev.Name);
}
}
if ev.Op&fsnotify.Rename == fsnotify.Rename {
fmt.Println( "重命名文件 : " , ev.Name);
w.watch.Remove(ev.Name);
}
if ev.Op&fsnotify.Chmod == fsnotify.Chmod {
fmt.Println( "修改权限 : " , ev.Name);
}
}
case err :=
{
fmt.Println( "error : " , err);
return ;
}
}
}
}();
}
func main() {
watch, _ := fsnotify.NewWatcher()
w := Watch{
watch: watch,
}
w.watchDir( "./tmp" );
select {};
}
|
Keputusan ujian adalah seperti berikut:
Selepas contoh di atas, kami menggunakan fsnotify untuk menulis fail konfigurasi pemantauan Jika fail konfigurasi diubah, mulakan semula perkhidmatan .
Kami mula-mula menulis program exe yang boleh dijalankan Kod server.go adalah seperti berikut:
1 2345678 9 10111213141516 1718192021222324252627282930 31323334353637 38 3940414243444546474849505152535455565758 |
package main;
import (
"io/ioutil"
"log"
"encoding/json"
"net"
"fmt"
"os"
"os/signal"
)
const (
confFilePath = "./conf/conf.json" ;
)
type Conf struct {
Port int `json:port`;
}
func main() {
data, err := ioutil.ReadFile(confFilePath);
if err != nil {
log.Fatal(err);
}
var c Conf;
err = json.Unmarshal(data, &c);
if err != nil {
log.Fatal(err);
}
lis, err := net.Listen( "tcp" , fmt.Sprintf( ":%d" , c.Port));
if err != nil {
log.Fatal(err);
}
log.Println( "server start" );
go func() {
ch := make(chan os.Signal);
signal.Notify(ch, os.Interrupt, os.Kill);
log.Println( "server exit" );
os.Exit(1);
}();
for {
conn, err := lis.Accept();
if err != nil {
continue ;
}
go func(conn net.Conn) {
defer conn.Close();
conn.Write([]byte( "hellon" ));
}(conn);
}
}
|
Gunakan arahan berikut untuk menyusun ke dalam fail exe
1
Kod pemantauan fsnotify3.go adalah seperti berikut:
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
94
95
96
97
98
99
100
101
102
102 104105106107108109110
111
|
package main;
import ( "github.com/fsnotify/fsnotify"
"log"
"fmt"
"os/exec"
"regexp"
"strconv"
"bytes"
"errors"
"os"
"path/filepath"
)
const (
confFilePath = "./conf" ;
)
func getPid(processName string) (int, error) {
buf := bytes.Buffer{};
cmd := exec.Command( "wmic" , "process" , "get" , "name,processid" );
cmd.Stdout = &buf;
cmd.Run();
cmd2 := exec.Command( "findstr" , processName);
cmd2.Stdin = &buf;
data, _ := cmd2.CombinedOutput();
if len(data) == 0 {
return -1, errors.New( "not find" );
}
info := string(data);
reg := regexp.MustCompile(`[0-9]+`);
pid := reg.FindString(info);
return strconv.Atoi(pid);
}
func startProcess(exePath string, args []string) error {
attr := &os.ProcAttr{
Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
Env: os.Environ(),
}
p, err := os.StartProcess(exePath, args, attr);
if err != nil {
return err;
}
fmt.Println(exePath, "进程启动" );
p.Wait();
return nil;
}
func main() {
watch, err := fsnotify.NewWatcher();
if err != nil {
log.Fatal(err);
}
defer watch.Close();
err = watch.Add(confFilePath);
if err != nil {
log.Fatal(err);
}
go func() {
for {
select {
case ev :=
{
if ev.Op&fsnotify.Write == fsnotify.Write {
fmt.Println(ev.Name, "文件写入" );
pid, err := getPid( "server.exe" );
exePath, _ := filepath.Abs( "./server.exe" )
if err != nil {
go startProcess(exePath, []string{});
} else {
process, err := os.FindProcess(pid);
if err == nil {
process.Kill();
fmt.Println(exePath, "进程退出" );
}
go startProcess(exePath, []string{});
} }
}
case err :=
{
fmt.Println( "error : " , err);
return ;
}
}
}
}();
🎜>
Kami menjalankan fail fsnotify3.go untuk memantau fail konfigurasi kami
Seperti yang anda lihat daripada rajah di atas, apabila kami ubah suai fail konfigurasi Apabila menukar nombor port, proses akan dimatikan terlebih dahulu dan kemudian proses akan dimulakan. select {};
}
Pembelajaran yang disyorkan: Tutorial Golang |
|
|
Atas ialah kandungan terperinci Bagaimana untuk melaksanakan pemantauan fail dalam golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!