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 相关文章推荐
ajax 缓存 问题 requestheader
Aug 01 Javascript
ExtJs默认的字体大小改变的几种方法(自己整理)
Apr 18 Javascript
动态加载script文件的两种方法
Aug 15 Javascript
XML文件转化成NSData对象的方法
Aug 12 Javascript
JavaScript基本语法学习教程
Jan 14 Javascript
jQuery+CSS3实现四种应用广泛的导航条制作实例详解
Sep 17 Javascript
Javascript基础回顾之(一) 类型
Jan 31 Javascript
基于EasyUI的基础之上实现树形功能菜单
Jun 28 Javascript
BootstrapTable加载按钮功能实例代码详解
Sep 22 Javascript
解决jQuery使用append添加的元素事件无效的问题
Aug 30 jQuery
jQuery 函数实例分析【函数声明、函数表达式、匿名函数等】
May 19 jQuery
Vue中使用wangeditor富文本编辑的问题
Feb 07 Vue.js
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
业余方法DIY电子管FM收音机
2021/03/02 无线电
php 用sock技术发送邮件的函数
2007/07/21 PHP
PHP取得一个类的属性和方法的实现代码
2011/05/22 PHP
PHP中通过语义URL防止网站被攻击的方法分享
2011/09/08 PHP
tp5框架无刷新分页实现方法分析
2019/09/26 PHP
laravel入门知识点整理
2020/09/15 PHP
javascript第一课
2007/02/27 Javascript
JS 学习笔记 防止发生命名冲突
2009/07/30 Javascript
JavaScript Array Flatten 与递归使用介绍
2011/10/30 Javascript
js中数组Array的一些常用方法总结
2013/08/12 Javascript
js实现固定显示区域内自动缩放图片的方法
2015/07/18 Javascript
解决jQuery使用JSONP时产生的错误
2015/12/02 Javascript
AngularJS 使用 UI Router 实现表单向导
2016/01/29 Javascript
Bootstrap入门书籍之(五)导航条、分页导航
2016/02/17 Javascript
基于vue2.0动态组件及render详解
2018/03/17 Javascript
JS装饰器函数用法总结
2018/04/21 Javascript
JavaScript递归函数解“汉诺塔”算法代码解析
2018/07/05 Javascript
vue实现word,pdf文件的导出功能
2018/07/31 Javascript
vue 修改 data 数据问题并实时显示的方法
2018/08/27 Javascript
vue中多路由表头吸顶实现的几种布局方式
2019/04/12 Javascript
vue设置导航栏、侧边栏为公共页面的例子
2019/11/01 Javascript
python获得一个月有多少天的方法
2015/06/04 Python
Python实现的redis分布式锁功能示例
2018/05/29 Python
python3 自动打印出最新版本执行的mysql2redis实例
2020/04/09 Python
CSS3教程(10):CSS3 HSL声明设置颜色
2009/04/02 HTML / CSS
CSS3实现闪烁动画效果的方法
2015/02/09 HTML / CSS
日本无添加化妆品:HABA
2016/08/18 全球购物
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
澳大利亚最受欢迎的女士度假服装:Kabana Shop
2020/10/10 全球购物
电子商务专业个人的自我评价
2013/12/19 职场文书
房地产广告词大全
2014/03/19 职场文书
党的群众路线教育实践方案
2014/05/11 职场文书
小学生常见病防治方案
2014/06/06 职场文书
民主评议党员自我鉴定
2014/10/21 职场文书
2016年第16个全民国防教育日宣传活动总结
2016/04/05 职场文书
Vue中foreach数组与js中遍历数组的写法说明
2021/06/05 Vue.js