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 相关文章推荐
地址栏上的一段语句,改变页面的风格。(教程)
Apr 02 Javascript
getElementsByTagName vs selectNodes效率 及兼容的selectNodes实现
Feb 26 Javascript
jquery中 $.expr使用实例介绍
Jun 09 Javascript
Window.Open如何在同一个标签页打开
Jun 20 Javascript
基于Flowplayer打造一款免费的WEB视频播放器附源码
Sep 06 Javascript
javascript实现tab切换的两个实例
Nov 05 Javascript
jquery实现邮箱自动填充提示功能
Nov 17 Javascript
AngularJS 2.0入门权威指南
Oct 08 Javascript
微信小程序报错:this.setData is not a function的解决办法
Sep 27 Javascript
node中的session的具体使用
Sep 14 Javascript
关于RxJS Subject的学习笔记
Dec 05 Javascript
Weex开发之地图篇的具体使用
Oct 16 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的几个常用数字判断函数代码
2012/04/24 PHP
PHP eval函数使用介绍
2013/12/08 PHP
php实现模拟登陆方正教务系统抓取课表
2015/05/19 PHP
python进程与线程小结实例分析
2018/11/11 PHP
js弹出模式对话框,并接收回传值的方法
2013/03/12 Javascript
javascript控制Div层透明属性由浅变深由深变浅逐渐显示
2013/11/12 Javascript
用JavaScript实现使用鼠标画线的示例代码
2014/08/19 Javascript
jQuery 遍历函数详解
2015/07/05 Javascript
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
2016/05/19 Javascript
深入理解JS继承和原型链的问题
2016/12/17 Javascript
一个炫酷的Bootstrap导航菜单
2016/12/28 Javascript
BootStrap Datepicker 插件修改为默认中文的实现方法
2017/02/10 Javascript
浅谈vue2 单页面如何设置网页title
2017/11/08 Javascript
vue-froala-wysiwyg 富文本编辑器功能
2019/09/19 Javascript
JS数组进阶示例【数组的几种函数用法】
2020/01/16 Javascript
vue 实现动态路由的方法
2020/07/06 Javascript
[01:04:01]2014 DOTA2华西杯精英邀请赛5 24 DK VS VG
2014/05/25 DOTA
[29:10]Ti4 冒泡赛第二天 NEWBEE vs Titan 3
2014/07/15 DOTA
[03:06]3分钟带你回顾DOTA2完美盛典&完美大师赛
2017/12/06 DOTA
Python实现的统计文章单词次数功能示例
2019/07/08 Python
Pandas操作CSV文件的读写实现方法
2019/11/13 Python
Python批量处理csv并保存过程解析
2020/05/16 Python
python中@property的作用和getter setter的解释
2020/12/22 Python
HTML5之SVG 2D入门2—图形绘制(基本形状)介绍及使用
2013/01/30 HTML / CSS
Java程序员面试90题
2013/10/19 面试题
优秀老师事迹材料
2014/02/05 职场文书
微信营销策划方案
2014/02/24 职场文书
航海技术专业毕业生求职信
2014/04/06 职场文书
幼儿园教师师德师风演讲稿:我自豪我是一名幼师
2014/09/10 职场文书
授权委托书(完整版)
2014/09/10 职场文书
2014第二批党的群众路线教育实践活动对照检查材料思想汇报
2014/09/18 职场文书
我们的节日重阳节活动总结
2015/03/24 职场文书
材料采购员岗位职责
2015/04/03 职场文书
阿凡达观后感
2015/06/10 职场文书
2019年幼儿园家长接送责任书
2019/10/29 职场文书
星际争霸:毕姥爷vs解冻03
2022/04/01 星际争霸