go linux监测文件变化

news/2024/4/13 10:30:58/文章来源:https://blog.csdn.net/A_super_C/article/details/136430628

go linux监测文件变化

文件改变内容有两种方式,效果一样,但执行方式有区别:

  1. 直接打开文件改,现在很多编辑器都是这样操作的
  2. 先删除原来的,再新创建写入一个替代原来的。比如vi/vim.这种方式会打断linux inotify原有的监测(就好比你有一部手机,一个人走过来给你砸了,再递给你一部同型号配置,内容备份了你原来的手机,但是新下载了个app。这时候你使用上用不出差别,但是它已经不是你原来的手机了).遇到这种情况时我们需要判断是否文件还存在,存在说明就是上述情况,然后需要重新监听文件状态

go linux监测文件变化,靠系统调用inotify.

演示代码

package mainimport ("errors""fmt""log""os""os/signal""strings""sync""syscall""unsafe"
)type FileLink struct {c        chan int64filename string
}
type FileWatcher struct {linkmap     map[int32]FileLinklink        map[string]int32resource_mu sync.Mutexfd          int
}const WATCH_FLAG = syscall.IN_MODIFY | syscall.IN_CLOSE_WRITE// 重新监听文件状态
func rewatch(fw *FileWatcher, wd *syscall.InotifyEvent) bool {finfo := fw.linkmap[wd.Wd]if _, err := os.Stat(finfo.filename); err != nil {fmt.Fprintln(os.Stderr, "not found "+finfo.filename+" "+err.Error())return false}fw.resource_mu.Lock()defer fw.resource_mu.Unlock()delete(fw.linkmap, wd.Wd)fmt.Println("rewatch " + finfo.filename)wid, err := syscall.InotifyAddWatch(fw.fd, finfo.filename, WATCH_FLAG)if wid < 0 {fmt.Fprintln(os.Stderr, "rewatch failed "+err.Error())return false}wd.Wd = int32(wid)fw.linkmap[wd.Wd] = finfofmt.Println("rewatch " + finfo.filename + " finished")return true
}func Status2String(status uint32) string {var ans []stringif status&syscall.IN_MODIFY > 0 {ans = append(ans, "modify")}if status&syscall.IN_CLOSE_WRITE > 0 {ans = append(ans, "close_write")}return strings.Join(ans, " ")
}
func (s *FileWatcher) AddWatch(filename_list ...string) ([]<-chan int64, error) {s.resource_mu.Lock()defer s.resource_mu.Unlock()var (errlist  []errorchanlist []<-chan int64)for _, name := range filename_list {wd, err := syscall.InotifyAddWatch(s.fd, name, WATCH_FLAG)if err != nil {errlist = append(errlist, err)} else {s.linkmap[int32(wd)] = FileLink{c: make(chan int64, 1), filename: name}s.link[name] = int32(wd)chanlist = append(chanlist, s.linkmap[int32(wd)].c)}}if len(errlist) > 0 {return chanlist, errors.Join(errlist...)}return chanlist, nil
}
func (s *FileWatcher) Delete(filename_list ...string) {s.resource_mu.Lock()defer s.resource_mu.Unlock()for _, name := range filename_list {if wd, ok := s.link[name]; ok {syscall.InotifyRmWatch(s.fd, uint32(wd))close(s.linkmap[wd].c)delete(s.link, name)delete(s.linkmap, wd)}}
}
func (s *FileWatcher) Close() error {return syscall.Close(s.fd)
}
func NewFileWatcher() (*FileWatcher, error) {var filewatcher FileWatcherfilewatcher.linkmap = make(map[int32]FileLink)filewatcher.link = make(map[string]int32)var err errorfilewatcher.fd, err = syscall.InotifyInit()if err != nil {return nil, err}go func() {var (buff  []byte = make([]byte, 1<<16)size  interr   errorevent *syscall.InotifyEvent)for {size, err = syscall.Read(filewatcher.fd, buff)if err == nil {if size < syscall.SizeofInotifyEvent {continue}//读取到的是inotifyevent 事件数组for i := 0; i <= size-syscall.SizeofInotifyEvent; i += syscall.SizeofInotifyEvent {event = (*syscall.InotifyEvent)(unsafe.Pointer(&buff[i]))if event.Mask&syscall.IN_IGNORED > 0 {if rewatch(&filewatcher, event) {event.Mask -= syscall.IN_IGNOREDif event.Mask&syscall.IN_MODIFY == 0 {event.Mask |= syscall.IN_MODIFY}} else {continue}}filewatcher.linkmap[event.Wd].c <- int64(event.Mask)// fmt.Println(filewatcher.linkmap[event.Wd].filename + " status " + Status2String(event.Mask))}} else {break}}}()return &filewatcher, nil
}
func main() {fw, err := NewFileWatcher()if err == nil {var chlist []<-chan int64chlist, err = fw.AddWatch("test.txt")if err == nil {ch := make(chan os.Signal, 1)signal.Notify(ch, os.Interrupt)go func() {<-chfw.Close()os.Exit(0)}()for {status := <-chlist[0]fmt.Println("test.txt status " + Status2String(uint32(status)))}} else {fw.Close()}}if err != nil {log.Fatalln(err.Error())}
}

效果展示

监测vscode 更改
在这里插入图片描述

监测vim更改识别
在这里插入图片描述

需要注意的点

这里我演示只演示了修改和关闭并写入(保存),如果需要监测其它状态,syscall.IN_开头的就是mask。每个值的作用定量名已经很明确了,不明白自行google含义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_997364.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot+vue+mysql项目使用的常用注解

实体类常用注解 Data Data 是一个 Lombok 提供的注解&#xff0c;使用 Data 注解可以简化代码&#xff0c;使代码更加简洁易读。 作用&#xff1a;自动为类生成常用的方法&#xff0c;包括 getter、setter、equals、hashCode 和 toString 等需要加Lombok的依赖 <depende…

vue系列——vscode,node.js vue开发环境搭建

第一步安装node.js 推荐使用nvm进行node.js 的安装 nvm(Node.js version manager) 是一个命令行应用&#xff0c;可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 可以去网上查找相关版本 我这里使用 nvm-setu… 链接:https://pan.baidu.com/s/1UEUtmzw5x…

【数据结构】红黑树(RBTree)

介绍 概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出两倍&#xff0c;因而是…

专家解读:2024年十大项目管理工具综合排名与评价

2024年涌现出一批新的项目管理工具&#xff0c;各具特色的功能和设计为企业解决了诸多的管理难题。今天我们就来盘点2024年的十款项目管理工具Zoho Projects、AgileMaster、PlanItAll、CommuniQ、WorkFlowRanger、GanttGenius、RiskAssessor、TeamHarmony、BudgetBoss、CloudCo…

智能控制:物联网智能插座对接文档

介绍 一开始买的某米的插座&#xff0c;但是好像接口不开放&#xff0c;所以找到了这个插座&#xff0c;然后自己开发了下&#xff0c;用接口控制插座开关。wifi的连接方式&#xff0c;通电后一般几秒后就会连接上wifi&#xff0c;这个时候通过接口发送命令给他。 产品图片 通…

#QT(DEMO)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a;打印"hello wolrd" 3.记录 &#xff08;1&#xff09;创建一个新工程&#xff1a; 新建好一个工程存放文件夹&#xff08;路径不能有中文&#xff09;,然后按下图配置 &#xff08;2&#xff09;点击widgets.ui拖入以…

聚焦两会 | 从2024年政府工作报告看网络安全新机

在今年的《政府工作报告》&#xff08;下面简称“报告”&#xff09;中&#xff0c;除了对2023年里我国所取得的重大成就作了全面总结外&#xff0c;针对2024年全年经济社会发展作出的部署安排引起全国人民的关注。报告中与网络安全相关的内容也引起网络安全行业相关从事人员的…

如何查看前端的vue项目是vue2还是vue3项目

1. 检查package.json文件 在项目的根目录下&#xff0c;打开package.json文件&#xff0c;查找dependencies或devDependencies部分中的vue条目。版本号将告诉你是Vue 2还是Vue 3。例如&#xff1a; Vue 2.x: "vue": "^2.x.x"Vue 3.x: "vue": &…

vue svelte solid 虚拟滚动性能对比

前言 由于svelte solid 两大无虚拟DOM框架&#xff0c;由于其性能好&#xff0c;在前端越来越有影响力。 因此本次想要验证&#xff0c;这三个框架关于实现表格虚拟滚动的性能。 比较版本 vue3.4.21svelte4.2.12solid-js1.8.15 比较代码 这里使用了我的 stk-table-vue(np…

微信小程序用户登陆和获取用户信息功能实现

官方文档&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 接口说明&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html 我们看官方这个图&#xff0c;梳理一下用户…

IEEE754标准的c语言阐述,以及几个浮点数常量

很多年前&#xff0c;调研过浮点数与整数之间的双射问题&#xff1a; win7 intel x64 cpu vs2013 c语言浮点数精度失真问题 最近重新学习了一下IEEE754标准&#xff0c;也许实际还有很多深刻问题没有被揭示。 计算机程序设计艺术&#xff0c;据说这本书中也有讨论。 参考&…

校招中的“熟悉linux操作系统”一般是指达到什么程度?

校招中的“熟悉linux操作系统”一般是指达到什么程度&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&am…

官网:随便搞个?那不如不搞,搞不好就给公司减分了。

官网建设确实需要认真对待&#xff0c;不能随便搞。一个粗制滥造的官网可能会给公司带来负面影响&#xff0c;降低品牌形象和用户体验。以下是一些官网建设的重要原则&#xff1a; 专业性&#xff1a;官网应该展示公司的专业性和专业知识。它应该以专业的设计、内容和功能来展示…

uipath调用js代码

1&#xff0c;调用js代码&#xff0c;不带参数&#xff0c;没有返回值 为了去掉按钮的disabled属性 function(){ document.getElementsByClassName(submitBtn)[0].removeAttribute(disabled); } 2&#xff0c;调用js代码&#xff0c;带参数&#xff0c;没有返回值 输入参数&a…

Day 6.有名信号量(信号灯)、网络的相关概念和发端

有名信号量 1.创建&#xff1a; semget int semget(key_t key, int nsems, int semflg); 功能&#xff1a;创建一组信号量 参数&#xff1a;key&#xff1a;IPC对像的名字 nsems&#xff1a;信号量的数量 semflg&#xff1a;IPC_CREAT 返回值&#xff1a;成功返回信号量ID…

Hololens 2应用开发系列(2)——MRTK基础知识及配置文件配置(上)

Hololens 2应用开发系列&#xff08;2&#xff09;——MRTK基础知识及配置文件配置 一、前言二、MRTK基础知识2.1 MRTK概述2.2 MRTK运行逻辑2.3 MRTK配置文件介绍2.4 MRTK服务 三、配置文件使用3.1 总配置文件3.2 相机配置3.3 其他配置 参考文献 一、前言 在前面的文章中&…

有一点好看的wordpress外贸独立站模板

手机配件wordpress外贸网站模板 充电器、移动电源、手机膜、手机电池、手机壳、手机转接头等手机配件wordpress外贸网站模板。 https://www.jianzhanpress.com/?p3809 车载电器wordpress外贸网站模板 车载吸尘器、空气净化器、行车记录仪、车载充电器、车载影音导航等车载电…

两数之和(c++ 、c)

给定一个整数数组nums和一个整数目标值target&#xff0c;请你再该数组中找出和为目标值target的那两个数&#xff0c;并返回它们的数组下标 题目介绍方法一思路及算法复杂度分析 方法二&#xff1a;哈希表什么是哈希表思路及算法C中unordered_map用法复杂度分析 方法三&#x…

C++ STL自定义排序

更具体的看【速记】C STL自定义排序 - 知乎 (zhihu.com) sort sort第三个位置放的greater<int>和less<int>萌新可能会弄错&#xff0c;这两个单词不是更大和更小的意思&#xff0c;而是大于和小于&#xff0c;并且比较就是自定义排序中的前者和后者。 如果是less…

【CSP试题回顾】201503-3-节日

CSP-201503-3-节日 关键点&#xff1a;格式化输出 在C中&#xff0c;格式化输出通常利用iostream库中的功能&#xff0c;特别是iomanip头文件提供的一系列操作符。这些操作符用于控制输出格式&#xff0c;如宽度、填充、对齐方式等。在你提供的代码中&#xff0c;用于格式化输…