golang怎麼實現文件監控

青灯夜游
發布: 2023-02-20 10:18:21
原創
4588 人瀏覽過

在golang中,可以利用fsnotify來實現檔案監控。 fsnotify是go語言跨平台檔案系統監控工具,實作了一個基於channel的、跨平台的即時監聽介面;golang透過fsnotify可監控文件,並透過檔案變更重啟程式。

golang怎麼實現文件監控

本教學操作環境:windows10系統、GO 1.18版本、Dell G3電腦。

在golang中,可以利用fsnotify來實現檔案監控。

golang 透過fsnotify監控文件,並透過文件變更重新啟動程式。

go語言跨平台檔案系統監控工具— fsnotify

#在linux 核心中,Inotify 是用來通知用戶空間程序檔案系統變化的機制。它監控檔案系統的變化,如檔案新建、修改、刪除等,並可以將相應的事件通知給應用程式。

Inotify 既可以監控文件,也可以監控目錄。當監控目錄時,它可以同時監控目錄及目錄中的各子目錄及檔案。 Golang 的標準函式庫 syscall 實現了這個機制。

為了進一步擴展和抽象, github.com/fsnotify/fsnotify 套件實現了一個基於 channel 的、跨平台的即時監聽介面。

fsnotify工具的使用

一、下載我們需要的套件

go get github.com/fsnotify/fsnotify
登入後複製

二、使用fsnotify監控檔案

21

1

2

3

##4

##5

#6

7

8

9

10

11

##12

13

14

15

16

#17

18

#19

20

22

23

24

25

26

27

28

2930

31

3233

34

3536

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"######### #######"fmt"#### ##

)

#func main() {

//建立一個監視物件

watch, err := fsnotify.NewWatcher();

# #iferr != nil {

###log.Fatal(err);

}#

defer watch.Close();defer watch.Close();

//新增要監控的對象,檔案或資料夾

err = watch.Add(

#". /tmp"

);

iferr != nil {

#log.Fatal(err);

#}

##//我們另啟一個goroutine來處理監控物件的事件

go func() {

#### # ######for### ###{############ ###1 ###case### ###ev := 以# } == fsnotify.Write {

# 以##}

emove == fsnotify.Remove {

log.Println(

"刪除文件: ", ev.Name);

}

name == fsnotify.Rename {

#log.Println("重命名文件: "

, ev.Name);

}

Chmod == fsnotify.Chmod {

# 以

}case

err :=

log.Println("error : "return

;}##o

#

#}

#}();

## |

#//循環

select {};

}

測試結果如下:

golang怎麼實現文件監控

我們在tmp目錄下的操作都被捕捉到了,但是fsnotify有一個問題,它無法遞歸的幫我們捕捉子目錄、孫子目錄的操作事件,這需要我們自已實現。

還有一個問題就是當們修改資料夾名稱時,fsnotify中event.Name仍然是原來的檔案名,這需要我們在重命名事件中,先移除先前的監控,然後再添加新的監控。

修改如下:

#82

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

################## #83######84######85#######86#######87#######88############## #####package main;############ ### #########import (######

"github.com/fsnotify/fsnotify"

#"fmt"

"path/filepath"

#"os"

"os"

##)

type 觀看 struct {

##watch *fsnotify.Watcher ;

}

#

//監控目錄

func (w *Watch) watchDir(dir string) {

//透過Walk來遍歷目錄下的所有子目錄

filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {

//這裡判斷是否為目錄,只需監控目錄即可

//目錄下的檔案也在監控範圍內,不需要我們一個一個加

ifinfo.IsDir() {

### ##path, err := filepath.Abs(path);

iferr !

#

returnerr;

# ###err = w.watch.Add(path);

##return

#err;# ###fmt.Println(

"監視器: "#, );#

##}

returnnil;

#});

#go func() {

#

for{

## ##

#case

ev :=

##

ifev.Op&fsnotify.Cre)

# fmt.Println(

"建立檔案: "##, ev.Name);## 建立文件的訊息,如果是目錄,則加入監控中

##fi, Stat;#1

##1

w .watch.Add(ev.Name);

ev.Name);

##

}#if

ev.Op&fsnotify.Write ==fmt.Println ("寫入檔案: "

, ev.Name);

# ”

'ifev.Op&fsnotify.Remove ====

##ev.Op&fsnotify.Remove ====#notify.Remove {#ev.

以###///若刪除檔案為目錄,則移除監控##fi, err := os.Stat(ev.Name) ;

#ifw.watch.Remove(ev.Name);

##, ev.Name);

}

#ifev.Op&fsnot

##fmt.Println(

"重新命名檔案: ", ev.Name);/如果重新命名檔案是目錄,則移除監控

#

//因為重複命名後,因為「重複命名」

//所以這裡就簡單粗爆的直接remove好了

)(

w.watch.Remove( ## 所》##}

ifev.Op&fsnotify.Chmod ==

fmt。 Println(

"權限: "##, ev.Name);修改 ”

}

##{

fmt.Println("錯誤: "

,錯誤);

#}#}

###}();

#}

##func main() {

watch, _ := fsnotify.NewWatcher()

#w := 觀看{

觀看:觀看,

}w.watchDir(

"./tmp"

);# ########選擇 {};##########

測試結果如下:

golang怎麼實現文件監控

經過上面的例子,我們透過fsnotify來寫一個監控設定文件,如果設定檔有修改,就重新啟動服務。

我們先寫一個可以執行的exe程序,server.go程式碼如下:

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

package main;

import (

"io/ioutil"

"log"

#" encoding/json"

"net"

"fmt"##

"fmt"

"os"#

"os/signal"

#)

#const (#confFilePath ="./conf/conf.json"

;

#)

### ### # ##

//我們這裡只是示範,設定項目只設定一個

type Conf struct {

Port int `json:port`;

}

#

func main( ) {

//讀取檔案內容

#data, err := ioutil .ReadFile(confFilePath);

iferr != nil {

##

#log.Fatal(err);

}

#var

c Conf;

//解析設定檔

##o# = json.Unmarshal(data, &c);

iferr != 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);#ch := make(chan os.Signal);

o 和.Kill);

###

##"server exit"

);

#####os.Exit(1);#################os.Exit(1);################# #### ######}();######

##for{

conn, err := lis.Accept();

#iferr != nil {

#;#

}

###{

defer conn.Close();

byte("hello\n"

));#}(conn);

}

#}

############### #使用下列指令,編譯成exe檔#####################1##################> ; go build server.go######################

監控檔案fsnotify3.go程式碼如下:

#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######103### ###104######105######106######107######108######109###

110

111

#package main;

import (

"github.com/fsnotify/fsnotify"

#「日誌」

「fmt」

「 os/exec」

#"regexp"

#"strconv"

#

#"strconv"#

#"strconv"

「位元組」

「錯誤」

#

"os"

"路徑/檔案路徑"

)

#

#const (

confFilePath =# "./conf";)##

#//取得進程ID

##func getPid(processName string) (int, error) {

#//透過wmic進程取得name,processid | findstr server.exe取得程序ID

buf := bytes.Buffer{};#cmd := exec.Command(

"wmic","進程"

##,

"取得",

"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(######"找不到"#### ##);############ ######}######

##info := string(data);

#//這裡透過正則將進程id提取出來

reg := regexp.MustCompile(`[0-9] `);

pid := reg.FindString(info);

returnstrconv.Atoi(pid);

#}

#//啟動程序

func startProcess(exePath string , args []string) error {

attr := &os.ProcAttr{

#//files指定新流程繼承的活動檔案物件

//前三名分別為,標準輸入、標準輸出、標準錯誤輸出

#》

#Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},

##

##//新流程的環境變數

Env: os.Environ(),

Env: os.Environ(),

}

#p, err := os.StartProcess(exePath, args, attr);

iferr != nil {

### #returnerr;

}

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);

iferr != nil {

log.Fatal(err) ;

}

//我們另啟一個goroutine來處理監控對象的事件

go func() {

#for{

select {

-watch.Events:{

# 修改

#ifev.Op&fs

fmt.Println(ev.Name,

##"檔案寫入"#);# //尋找程序

,##.#

//獲取

exePath, _ := filepath.Abs ("./server.exe"

)

{##

#go startProcess(exePath, []string{ });

#}#else##//找出流程,並退出

).

》 if

err == nil {

且為

process.Kill();;

##//啟動程序

#go}

#

}

case## # ###err := }

## 1 }

}();

##

#//循環

#select {};

}

golang怎麼實現文件監控

golang怎麼實現文件監控

#我們執行fsnotify3.go檔案來監控我們的設定檔
############透過上面的圖可以看到,當我們修改設定檔中的連接埠號碼時,會先kill掉進程,然後再啟動一個進程。 ###############推薦學習:###Golang教學############

以上是golang怎麼實現文件監控的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!