ホームページ > バックエンド開発 > Golang > golangでファイル監視を実装する方法

golangでファイル監視を実装する方法

青灯夜游
リリース: 2023-02-20 10:18:21
オリジナル
4695 人が閲覧しました

golang では、fsnotify を使用してファイル監視を実装できます。 fsnotify は Go 言語のクロスプラットフォーム ファイル システム監視ツールで、チャネルベースのクロスプラットフォーム リアルタイム監視インターフェイスを実装しています。golang は fsnotify を通じてファイルを監視し、ファイルの変更を通じてプログラムを再起動できます。

golangでファイル監視を実装する方法

このチュートリアルの動作環境: Windows 10 システム、GO バージョン 1.18、Dell G3 コンピューター。

golang では、fsnotify を使用してファイル監視を実装できます。

golang は、fsnotify を通じてファイルを監視し、ファイルの変更を通じてプログラムを再起動します。

Go 言語のクロスプラットフォーム ファイル システム監視ツール - fsnotify

Linux カーネルでは、Inotify は通知に使用されるツールです。ユーザー 空間プログラム ファイル システム変更のメカニズム。ファイルの作成、変更、削除などのファイル システムの変更を監視し、対応するイベントをアプリケーションに通知できます。

Inotify はファイルとディレクトリの両方を監視できます。ディレクトリを監視する場合、ディレクトリとそのディレクトリ内の各サブディレクトリおよびファイルを同時に監視できます。 Golang の標準ライブラリ syscall はこのメカニズムを実装しています。

さらに拡張および抽象化するために、github.com/fsnotify/fsnotify パッケージはチャネルベースのクロスプラットフォームのリアルタイム監視インターフェイスを実装します。

fsnotify ツールの使用法

1. 必要なパッケージをダウンロードします

go get github.com/fsnotify/fsnotify
ログイン後にコピー

2. fsnotify を使用してファイルを監視します

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

#パッケージメイン;

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);##// のイベントを処理するために別の goroutine を開始します。監視対象オブジェクト

go func() {

for

{

# case

ev:=< -watch.events:###stos ## //名前を変更しました

##ev.Op&fsnotify.Create == fsnotify.Create {<p class="line number34 index33 alt1"><code class="js spaces"> log.Println("ファイルの作成: ", ev.Name);

##}

log.Println("ファイルの書き込み: "

、ev.名前);

}

#log.Println(

"ファイルの削除: "

, ev.Name); ##}

##log.Println("ファイル名の変更: ", ev.Name);

}

Log.println (

「変更権限:」 、Ev.name); #err :=

###### ####戻る######;########### ############ ### ### ### <p class="line number51 index50 alt2"><code class="js spaces"> //ループ

select {};

}

テスト結果は次のとおりです:

golangでファイル監視を実装する方法

tmp ディレクトリ内のすべての操作がキャプチャされましたが、fsnotify に問題があります。サブディレクトリを再帰的にキャプチャすることはできません。 . 孫子ディレクトリの操作イベントは自分で実装する必要があります。

もう 1 つの問題は、フォルダー名を変更しても、fsnotify のevent.Name が元のファイル名のままであることです。これには、最初に名前変更イベント内の以前の監視を削除してから、新しい監視を追加する必要があります。

次のように変更します:

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

##パッケージ メイン;

インポート (

"github.com/fsnotify/fsnotify"

"fmt"

"パス/ファイルパス"

"os"

)

type Watch 構造体 {

watch *fsnotify.Watcher ;

}

//監視ディレクトリ

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

//Walk

を介してディレクトリの下にあるすべてのサブディレクトリを走査します

//ディレクトリかどうかを判断するには、ディレクトリを監視するだけで済みます

//ディレクトリ内のファイルディレクトリも監視範囲内なので必要ありません 1つずつ追加します

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

if

err != nil {

# return err;

} ##});

##go func() {

## ev:=&lt; -w.watch.events:

fmt.println( "ファイルの作成: "

、ev.Name);

## に関する情報ファイルを作成すると、それがディレクトリの場合、監視に追加されます

## in .watch.add(ev.name);

fmt.println ("監視の追加: ", EV.NAME);

#} #} ## (

「ファイルへの書き込み: " 、ev.名前);

##if

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

<p class="line number51 index50 alt2"><code class="js spaces"> fmt.Println("ファイルの削除: ", ev.Name);

#//削除されたファイルがディレクトリの場合は、監視を削除します

> ;

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

##、ev.Name);

## stue fmt.println( "rename file:"

、ev.name); /名前変更されたファイルがディレクトリの場合は、監視を削除します

//ここでは os.Stat を使用してディレクトリであるかどうかを判断できないことに注意してください

# // 名前変更後、Go は情報を取得するための元のファイルを見つけることができなくなるため

#// そこで、これを削除する簡単かつ大雑把な方法を紹介します。

##}

if ev.Op&fsnotify.Chmod == fsnotify.Chmod {

fmt. Println("修改权制限 : ", ev.Name);

}

}

case err :=

{

fmt.Println("エラー : 「、エラー);

return;

}

}

}

}();

}

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

パッケージ メイン;

インポート (

「io/ioutil」

「ログ」

" エンコーディング/json"

"net"

"fmt 「

「os」

「os/シグナル」

)

##const (

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

)

<p class="line number17 index16 alt2"><code class="js comments">//ここではデモを行っているだけです。設定項目は 1 つだけを設定します。

type Conf struct {

Port int `json:port`;

}

func main( ) {

//ファイルの内容を読み取ります

データ、エラー: = 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.Println(

"サーバー起動");

go func(){

。.kill);

#"サーバー終了"); os.Exit(1);

}();

#for {

##conn、err := lis.Accept();

##;

#go func(conn net.Conn) {

# 操縦 conn.close ();

# Conn.write ([] byte(

"hello\n"));

##}( conn);

}}

#次のコマンドを使用して exe ファイルにコンパイルします

#1

> ; サーバーを構築する.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

パッケージメイン;

import (

"github.com/fsnotify/fsnotify"

"ログ"

"fmt"

"os/exec"

「regexp」

「strconv」

「バイト」

「エラー」

"os"

"パス/ファイルパス"

)

const (

confFilePath = "./conf";

)

//获取进程ID

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

//wmic プロセス経由 get name,processid | findstr server.exe获取进程ID

buf := bytes.Buffer{};

cmd := exec.Command("wmic", "プロセス", "get" , "name,processid");

cmd.Stdout = &buf;

cmd.Run();

cmd2 := exec.Command("findstr", processName);

cmd2.Stdin = &buf;

data, _ := cmd2.CombinedOutput();

if len(データ) == 0 {

return -1、エラー。New(「見つかりません」);

}

info := string(data);

<p class="line number34 index33 alt1"><code class="js spaces"> //ここでは、プロセス ID が正規表現によって抽出されます

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

pid := reg.FindString(info);

return strconv.Atoi(pid);

}

//プロセスを開始します

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

//files は、新しいプロセスによって継承されるアクティブなファイル オブジェクトを指定します

//最初の 3 つは標準入力、標準出力、および標準エラー出力です

//新しいプロセスの環境変数

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 {

監視を延期します。閉じる();

<p class="line number66 index65 alt1"><code class="js spaces"> //監視対象ファイルを追加

err = watch.Add(confFilePath);

#if err != nil {

# ;

}

//監視オブジェクト Event

を処理する別の goroutine を開始します。

-watch.イベント:

#fmt.Println を変更します。 (ev.Name, "ファイル書き込み");

## //プロセスの検索

## // 実行ファイルの絶対パスを取得

# EXEPATH, _: = ファイルパス.abs( "./ server.exe"

{

;<p class="line number87 index86 alt2"><code class="js spaces"> stos if err == nil {

プロセス。殺す();########### ############# ######} ############### //

# Go StartProcess(exepath、[] String {});

err:=&lt; - watch.Errors:fmt.Println(

"エラー: 「

、エラー);# # ;

###### を通して }########### ######}();############ ### ######

//ループ

{}を選択;

}

fsnotify3.go ファイルを実行して構成ファイルを監視します

あなたと同じように上の図からわかるように、構成ファイル内のポート番号を変更すると、最初にプロセスが強制終了され、次にプロセスが開始されます。

推奨学習: Golang チュートリアル

以上がgolangでファイル監視を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート