GoFrame 文件監(jiān)控-gfsnotify

2022-04-11 09:27 更新

?gfsnotify?能監(jiān)控指定文件/目錄的改變,如文件的增加、刪除、修改、重命名等操作。

使用方式:

import "github.com/gogf/gf/v2/os/gfsnotify"

接口文檔:

https://pkg.go.dev/github.com/gogf/gf/v2/os/gfsnotify

推薦使用?gfsnotify?模塊提供的?Add?和?Remove?模塊方法,用于添加監(jiān)控和取消監(jiān)控。推薦原因見隨后章節(jié)說明。

此外也可能通過?New?方法創(chuàng)建一個監(jiān)控管理對象之后再進行監(jiān)控管理。其中,添加監(jiān)控的時候需要給定觸發(fā)監(jiān)控時的回調(diào)函數(shù),參數(shù)類型為?*gfsnotify.Event?對象指針。

添加監(jiān)聽

package main

import (
    "github.com/gogf/gf/v2/os/gfsnotify"
    "github.com/gogf/gf/v2/os/glog"
)

func main() {
    // /home/john/temp 是一個目錄,當(dāng)然也可以指定文件
    path := "/home/john/temp"
    _, err := gfsnotify.Add(path, func(event *gfsnotify.Event) {
        if event.IsCreate() {
            glog.Println("創(chuàng)建文件 : ", event.Path)
        }
        if event.IsWrite() {
            glog.Println("寫入文件 : ", event.Path)
        }
        if event.IsRemove() {
            glog.Println("刪除文件 : ", event.Path)
        }
        if event.IsRename() {
            glog.Println("重命名文件 : ", event.Path)
        }
        if event.IsChmod() {
            glog.Println("修改權(quán)限 : ", event.Path)
        }
        glog.Println(event)
    })

    // 移除對該path的監(jiān)聽
    // gfsnotify.Remove(path)

    if err != nil {
        glog.Fatalln(err)
    } else {
        select {}
    }
}

其中?/home/john?參數(shù)為一個目錄,?gfsnotify.Add?方法默認(rèn)為遞歸監(jiān)控,也就是說當(dāng)目錄下的文件(包括子目錄下的文件)發(fā)生變化時,也會收到文件監(jiān)控信息回調(diào)。

當(dāng)我們在?/home/john?目錄下創(chuàng)建/刪除/修改文件時,可以看到?gfsnotify?監(jiān)控到了文件的修改并輸出了對應(yīng)的事件信息。

移除監(jiān)聽

移除監(jiān)聽我們可以使用?Remove?方法,會移除對整個文件/目錄的監(jiān)聽。

當(dāng)對同一個文件/目錄存在多個監(jiān)聽回調(diào)時,我們可以通過?RemoveCallback?方法移除指定的回調(diào)。方法參數(shù)?callbackId?是在添加監(jiān)聽時返回的?Callback?對象的唯一ID。

使用示例1:

package main

import (
    "github.com/gogf/gf/v2/os/gfsnotify"
    "github.com/gogf/gf/v2/os/glog"
    "github.com/gogf/gf/v2/os/gtimer"
    "time"
)

func main() {
    c1, err := gfsnotify.Add("/home/john/temp/log", func(event *gfsnotify.Event) {
        glog.Println("callback1")
    })
    if err != nil {
        panic(err)
    }
    c2, err := gfsnotify.Add("/home/john/temp/log", func(event *gfsnotify.Event) {
        glog.Println("callback2")
    })
    if err != nil {
        panic(err)
    }
    // 5秒后移除c1的回調(diào)函數(shù)注冊,僅剩c2
    gtimer.SetTimeout(5*time.Second, func() {
        gfsnotify.RemoveCallback(c1.Id)
        glog.Println("remove callback c1")
    })
    // 10秒后移除c2的回調(diào)函數(shù)注冊,所有的回調(diào)都移除,不再有任何打印信息輸出
    gtimer.SetTimeout(10*time.Second, func() {
        gfsnotify.RemoveCallback(c2.Id)
        glog.Println("remove callback c2")
    })

    select {}
}

使用示例2:

package main

import (
    "github.com/gogf/gf/v2/os/gfsnotify"
    "github.com/gogf/gf/v2/os/glog"
    "github.com/gogf/gf/v2/os/gtimer"
    "time"
)

func main() {
    callback, err := gfsnotify.Add("/home/john/temp", func(event *gfsnotify.Event) {
        glog.Println("callback")
    })
    if err != nil {
        panic(err)
    }

    // 在此期間創(chuàng)建文件、目錄、修改文件、刪除文件

    // 20秒后移除回調(diào)函數(shù)注冊,所有的回調(diào)都移除,不再有任何打印信息輸出
    gtimer.SetTimeout(20*time.Second, func() {
        gfsnotify.RemoveCallback(callback.Id)
        glog.Println("remove callback")
    })

    select {}
}

fs.inotify.max_user_instances與fs.inotify.max_user_watches

在?*nix?系統(tǒng)下,?gfsnotify?模塊使用的是系統(tǒng)的?inotify?特性來實現(xiàn)的文件/目錄監(jiān)控,因此該功能在使用時會受到系統(tǒng)的兩個內(nèi)核函數(shù)限制:

  • ?fs.inotify.max_user_instances?:表示當(dāng)前用戶可創(chuàng)建的?inotify?監(jiān)控實例數(shù)量,即?gfsnotify.New?方法創(chuàng)建的?Watcher?對象數(shù)量,一個?Watcher?對象對應(yīng)系統(tǒng)的一個?inotify?實例,系統(tǒng)默認(rèn)數(shù)量為:?128?;
  • ?fs.inotify.max_user_watches?:表示一個?inotify?實例可添加的監(jiān)控文件隊列大小,往同一個?inotify?添加的監(jiān)控文件超過該數(shù)量限制則會失敗,并且會有系統(tǒng)錯誤日志,系統(tǒng)默認(rèn)數(shù)量往往為:?8192?(有的系統(tǒng)該數(shù)值會比較大一些);


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號