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 相关文章推荐
DLL+ ActiveX控件+WEB页面调用例子
Aug 07 Javascript
两种常用的javascript数组去重方法思路及代码
Mar 26 Javascript
jQuery Mobile的loading对话框显示/隐藏方法分享
Nov 26 Javascript
jQuery跨域问题解决方案
Aug 03 Javascript
jquery性能优化高级技巧
Aug 24 Javascript
Bootstrap每天必学之工具提示(Tooltip)插件
Apr 26 Javascript
深入解析JavaScript中的arguments对象
Jun 12 Javascript
Angularjs 实现移动端在线测评效果(推荐)
Apr 05 Javascript
layui前段框架日期控件使用方法详解
May 19 Javascript
JS实现烟花爆炸效果
Mar 10 Javascript
vue 子组件watch监听不到prop的解决
Aug 09 Javascript
Ajax实现三级联动效果
Oct 05 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 adodb操作mysql数据库
2009/03/19 PHP
单一index.php实现PHP任意层级文件夹遍历(Zjmainstay原创)
2012/07/31 PHP
PHP系列学习之日期函数使用介绍
2012/08/18 PHP
php中使用getimagesize获取图片、flash等文件的尺寸信息实例
2014/04/29 PHP
PHP遍历目录并返回统计目录大小
2014/06/09 PHP
简单谈谈favicon
2015/06/10 PHP
Laravel框架基于ajax实现二级联动功能示例
2019/01/17 PHP
PHP实现字符串的全排列详解
2019/04/24 PHP
javascript脚本编程解决考试分数统计问题
2008/10/18 Javascript
jQuery 使用手册(七)
2009/09/23 Javascript
js 利用image对象实现图片的预加载提高访问速度
2013/03/29 Javascript
jQuery表格排序组件-tablesorter使用示例
2014/05/26 Javascript
jQuery选择器源码解读(二):select方法
2015/03/31 Javascript
js实现div拖动动画运行轨迹效果代码分享
2015/08/27 Javascript
JS传递对象数组为参数给后端,后端获取的实例代码
2016/06/28 Javascript
bootstrap switch开关组件使用方法详解
2017/08/22 Javascript
基于webpack-hot-middleware热加载相关错误的解决方法
2018/02/22 Javascript
详解CommonJS和ES6模块循环加载处理的区别
2018/12/26 Javascript
微信小程序实现的图片保存功能示例
2019/04/24 Javascript
python文档字符串(函数使用说明)使用详解
2019/07/30 Python
浅析Django 接收所有文件,前端展示文件(包括视频,文件,图片)ajax请求
2020/03/09 Python
Django 项目布局方法(值得推荐)
2020/03/22 Python
Tensorflow tf.nn.depthwise_conv2d如何实现深度卷积的
2020/04/20 Python
利用HTML5+css3+jquery+weui实现仿微信聊天界面功能
2018/01/08 HTML / CSS
雅诗兰黛香港官网:Estee Lauder香港
2017/09/26 全球购物
Farah官方网站:男士服装及配件
2019/11/01 全球购物
进程的查看和调度分别使用什么命令
2013/12/14 面试题
给实习单位的感谢信
2014/02/01 职场文书
高中军训第一天感言
2014/03/06 职场文书
银行职员自我鉴定
2014/04/20 职场文书
中国梦主题教育活动总结
2014/05/05 职场文书
公司承诺书怎么写
2014/05/24 职场文书
2015年办公室主任工作总结
2015/04/09 职场文书
学历证明样本
2015/06/16 职场文书
跳高加油稿
2015/07/21 职场文书
如何利用python和DOS获取wifi密码
2021/03/31 Python