node.js 如何监视文件变化


Posted in Javascript onSeptember 01, 2020

fs.FSWatcher

fs.FSWatcher类 继承了 EventEmitter,用于监视文件变化,调用 fs.watch 后返回一个 fs.FSWatcher 实例,每当指定监视的文件被修改时,实例会触发事件调用回调函数

fs.watch('./tmp', (eventType, filename) => {
 if (filename) {
  console.log(filename);
 }
});

fs.watch()

fs.watch(filename[, options][, listener]) 监视文件变化,返回 fs.FSWatcher 实例

1.filename:文件或文件夹路径

2.options

  • encoding
  • recursive:默认值 false,应该监视所有子目录,还是仅监视当前目录,仅在 macOS 和 Windows 上支持
  • persistent:默认值 true,指示如果文件已正被监视,进程是否应继续运行
  • listener(eventType, filename):文件变化回调函数

eventType 主要是 renamechange ,在大多数平台上,文件在目录中出现或消失时触发 'rename' 事件,在 Windows 上,如果监视的目录被移动或重命名,则不会触发任何事件,当监视的目录被删除时,则报告 EPERM 错误

fs.watch('./', { recursive: true }, (eventType, filename) => {
 console.log(eventType, filename);
});

fs.watchFile()

fs.watchFile(filename[, options], listener) 用于监视文件变化

1.filename

2.options

  • biginit:默认值 false,指定回调 stat 中的数值是否为 biginit 类型
  • persistent:默认值 true,当文件正在被监视时,进程是否应该继续运行
  • interval:默认值 5007,用来指定轮询频率(ms)

3.listener(currentStats, previousStats):listener 有两个参数,当前的 stat 对象和之前的 stat 对象
要在修改文件时收到通知,则需要比较 curr.mtime prev.mtime

const fs = require('fs');

fs.watchFile('./test.txt', { interval: 100 }, (curr, prev) => {
 console.log('当前的最近修改时间是: ' + curr.mtime);
 console.log('之前的最近修改时间是: ' + prev.mtime);
});

const tid = setInterval(() => {
 fs.appendFile('./test.txt', 'Hello, world!\n', err => {
  if (err) throw err;
  console.log('文件修改完成');
 });
}, 300);

setTimeout(() => {
 clearInterval(tid);
 fs.unwatchFile('./test.txt');
}, 2000);

fs.watch() 与 fs.watchFile()

因为 fs.watchFile() 使用轮训方式检测文件变化,如果不设置 interval 或者设置较高的值会发现文件变化的监视有延迟
而 fs.watch() 监听操作系统提供的事件,而且可以监视目录变化,使用 fs.watch() 比 fs.watchFile() 更高效,平常应尽可能使用 fs.watch() 代替 fs.watchFile()

当然 fs.watch() 依赖操作系统的实现,在不同平台上表现会有差异

  • Linux 操作系统使用 inotify
  • 在 macOS 系统使用 FSEvents
  • 在 windows 系统使用 ReadDirectoryChangesW

fs.unwatchFile

fs.unwatchFile(filename[, listener]) 停止监视 filename 的变化,如果指定了 listener,则仅移除此特定监听器,否则将移除所有监听器,从而停止监视 filename

fs.unwatchFile('./test.txt');

社区选择

fs.watchFile() 性能问题,fs.watch() 平台不一致等两个方法都有不尽如人意的地方

Node.js fs.watch:

MacOS 有时候不提供 filename
在部分场景不触发修改事件(MacOS Sublime)
经常一次修改两次触发事件
大部分文件变化 eventType 都是 rename.
未提供简单的监视文件树方式

Node.js fs.watchFile:

事件处理问题和 fs.watch 一样烂
没有嵌套监听
CPU 消耗大

https://www.npmjs.com/package/chokidar

日常在监视文件变化可以选择社区的优秀方案

  1. node-watch
  2. chokidar
const chokidar = require('chokidar');
 
// One-liner for current directory
chokidar.watch('.').on('all', (event, path) => {
 console.log(event, path);
});
// Initialize watcher.
const watcher = chokidar.watch('file, dir, glob, or array', {
 ignored: /(^|[\/\\])\../, // ignore dotfiles
 persistent: true
});
 
// Something to use when events are received.
const log = console.log.bind(console);
// Add event listeners.
watcher
 .on('add', path => log(`File ${path} has been added`))
 .on('change', path => log(`File ${path} has been changed`))
 .on('unlink', path => log(`File ${path} has been removed`));
 
// More possible events.
watcher
 .on('addDir', path => log(`Directory ${path} has been added`))
 .on('unlinkDir', path => log(`Directory ${path} has been removed`))
 .on('error', error => log(`Watcher error: ${error}`))
 .on('ready', () => log('Initial scan complete. Ready for changes'))
 .on('raw', (event, path, details) => { // internal
  log('Raw event info:', event, path, details);
 });

以上就是node.js 如何监视文件变化的详细内容,更多关于node.js 监视文件的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
用javascript实现计算两个日期的间隔天数
Aug 14 Javascript
JavaScript修改css样式style
Apr 15 Javascript
javascript实现的网页局布刷新效果
Dec 01 Javascript
JavaScript初学者应注意的七个细节详细介绍
Dec 27 Javascript
jQuery响应enter键的实现思路
Apr 18 Javascript
基于jQuery实现文本框缩放以及上下移动功能
Nov 24 Javascript
Knockout自定义绑定创建方法
Dec 26 Javascript
JavaScript中join()、splice()、slice()和split()函数用法示例
Aug 24 Javascript
vue点击input弹出带搜索键盘并监听该元素的方法
Aug 25 Javascript
VUE v-for循环中每个item节点动态绑定不同函数的实例
Sep 26 Javascript
微信小程序如何连接Java后台
Aug 08 Javascript
React学习之JSX与react事件实例分析
Jan 06 Javascript
JS JQuery获取data-*属性值方法解析
Sep 01 #jQuery
谈谈node.js中的模块系统
Sep 01 #Javascript
JavaScript浅层克隆与深度克隆示例详解
Sep 01 #Javascript
VUE子组件向父组件传值详解(含传多值及添加额外参数场景)
Sep 01 #Javascript
vue离开当前页面触发的函数代码
Sep 01 #Javascript
Vue 实现监听窗口关闭事件,并在窗口关闭前发送请求
Sep 01 #Javascript
Node.js web 应用如何封装到Docker容器中
Sep 01 #Javascript
You might like
支持中文的PHP按字符串长度分割成数组代码
2015/05/17 PHP
PHP登录验证码的实现与使用方法
2016/07/07 PHP
浅谈PHP正则中的捕获组与非捕获组
2016/07/18 PHP
详解Yii2 定制表单输入字段的标签和样式
2017/01/04 PHP
用于table内容排序
2006/07/21 Javascript
jquery的ajax请求全面了解
2013/03/20 Javascript
关于JS管理作用域的问题
2013/04/10 Javascript
document节点对象的获取方式示例介绍
2013/12/24 Javascript
Javascript高级技巧分享
2014/02/25 Javascript
IE中图片的onload事件无效问题和解决方法
2014/06/06 Javascript
JavaScript中split() 使用方法汇总
2015/04/17 Javascript
nodejs爬虫抓取数据之编码问题
2015/07/03 NodeJs
javascript实现抽奖程序的简单实例
2016/06/07 Javascript
jQuery替换节点用法示例(使用replaceWith方法)
2016/09/08 Javascript
js控制div层的叠加简单方法
2016/10/15 Javascript
浅谈JavaScript正则表达式-非捕获性分组
2017/03/08 Javascript
JS中跳出循环的示例代码
2017/09/14 Javascript
Vue.js更改调试地址端口号的实例
2018/09/19 Javascript
element-ui封装一个Table模板组件的示例
2021/01/04 Javascript
怎样使用Python脚本日志功能
2016/08/14 Python
Python中强大的命令行库click入门教程
2016/12/26 Python
Python3.X 线程中信号量的使用方法示例
2017/07/24 Python
Python读取excel指定列生成指定sql脚本的方法
2018/11/28 Python
python3+selenium实现qq邮箱登陆并发送邮件功能
2019/01/23 Python
Python使用统计函数绘制简单图形实例代码
2019/05/15 Python
python 通过 pybind11 使用Eigen加速代码的步骤
2020/12/07 Python
澳大利亚当地最大的时装生产商:Cue
2018/08/06 全球购物
用你熟悉的语言写一个连接ORACLE数据库的程序,能够完成修改和查询工作
2012/06/11 面试题
中介公司区域经理岗位职责范本
2014/03/02 职场文书
2014年教师节演讲稿范文
2014/09/10 职场文书
学生上课说话检讨书
2014/10/25 职场文书
六年级语文下册教学计划
2015/01/22 职场文书
汽车销售助理岗位职责
2015/04/14 职场文书
禁毒主题班会教案
2015/08/14 职场文书
解决Goland 同一个package中函数互相调用的问题
2021/05/06 Golang
USB TYPE-C 或将成为所有智能手机充电标准
2022/04/21 数码科技