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 相关文章推荐
各浏览器对link标签onload/onreadystatechange事件支持的差异分析
Apr 27 Javascript
javascript函数以及基础写法100多条实用整理
Jan 13 Javascript
jquery mobile 实现自定义confirm确认框效果的简单实例
Jun 17 Javascript
AngularGauge 属性解析详解
Sep 06 Javascript
JS中微信小程序自定义底部弹出框
Dec 22 Javascript
angular4模块中给标签添加背景图的实现方法
Sep 15 Javascript
bootstrap 点击空白处popover弹出框隐藏实例
Jan 24 Javascript
json对象及数组键值的深度大小写转换问题详解
Mar 30 Javascript
微信jssdk逻辑在vue中的运用详解
Nov 14 Javascript
vue项目中锚点定位替代方式
Nov 13 Javascript
Vue中常用rules校验规则(实例代码)
Nov 14 Javascript
三步搞定:Vue.js调用Android原生操作
Sep 07 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中使用Oracle数据库(6)
2006/10/09 PHP
PHP 日常开发小技巧
2009/09/23 PHP
php中ob_get_length缓冲与获取缓冲长度实例
2014/11/20 PHP
CI框架附属类用法分析
2018/12/26 PHP
js获取当前select 元素值的代码
2010/04/19 Javascript
获取服务器传来的数据 用JS去空格的正则表达式
2012/03/26 Javascript
用jQuery实现一些导航条切换,显示隐藏的实例代码
2013/06/08 Javascript
php跨域调用json的例子
2013/11/13 Javascript
深入理解JavaScript是如何实现继承的
2013/12/12 Javascript
JQuery EasyUI 加载两次url的原因分析及解决方案
2014/08/18 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
js解决movebox移动问题
2016/03/29 Javascript
利用JavaScript判断浏览器类型及版本
2016/08/23 Javascript
vue2.0多条件搜索组件使用详解
2020/03/26 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
bootstrap中的导航条实例代码详解
2019/05/20 Javascript
微信小程序获取用户绑定手机号方法示例
2019/07/21 Javascript
python改变日志(logging)存放位置的示例
2014/03/27 Python
在Python的Django框架中用流响应生成CSV文件的教程
2015/05/02 Python
python 网络编程常用代码段
2016/08/28 Python
python excel使用xlutils类库实现追加写功能的方法
2018/05/02 Python
python 统计数组中元素出现次数并进行排序的实例
2018/07/02 Python
对numpy中向量式三目运算符详解
2018/10/31 Python
Linux 修改Python命令的方法示例
2018/12/03 Python
python引用(import)某个模块提示没找到对应模块的解决方法
2019/01/19 Python
详解基于python-django框架的支付宝支付案例
2019/09/23 Python
python 牛顿法实现逻辑回归(Logistic Regression)
2020/10/15 Python
Pytorch自定义Dataset和DataLoader去除不存在和空数据的操作
2021/03/03 Python
2014年电教工作总结
2014/12/19 职场文书
少先队工作总结2015
2015/05/13 职场文书
运动会广播稿100字
2015/08/19 职场文书
2016年党员创先争优公开承诺书
2016/03/25 职场文书
用Python提取PDF表格的方法
2021/04/11 Python
Spring Boot实战解决高并发数据入库之 Redis 缓存+MySQL 批量入库问题
2022/02/12 Redis
十大最强飞行系宝可梦,BUG燕上榜,第二是飞行系王者
2022/03/18 日漫
MySQL如何使备份得数据保持一致
2022/05/02 MySQL