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 相关文章推荐
使用jquery局部刷新(jquery.load)从数据库取出数据
Jan 22 Javascript
java和javascript获取word文档的书签位置对比
Jun 19 Javascript
JavaScript声明变量时为什么要加var关键字
Sep 29 Javascript
js实现九宫格图片半透明渐显特效的方法
Feb 16 Javascript
JavaScript实现点击单元格改变背景色的方法
Feb 12 Javascript
基于Jquery Ajax type的4种类型(详解)
Aug 02 jQuery
jQuery初级教程之网站品牌列表效果
Aug 02 jQuery
webpack 模块热替换原理
Apr 09 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
Feb 15 jQuery
微信小程序嵌入腾讯视频源过程详解
Aug 08 Javascript
javascript 代码是如何被压缩的示例代码
May 06 Javascript
vue项目使用$router.go(-1)返回时刷新原来的界面操作
Jul 26 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入门源程序
2006/10/09 PHP
php数组总结篇(一)
2008/09/30 PHP
php魔术方法与魔术变量、内置方法与内置变量的深入分析
2013/06/03 PHP
解密ThinkPHP3.1.2版本之独立分组功能应用
2014/06/19 PHP
浅谈php优化需要注意的地方
2014/11/27 PHP
php递归json类实例
2014/12/02 PHP
阿里云PHP SMS短信服务验证码发送方法
2017/07/11 PHP
PHP抽象类和接口用法实例详解
2019/07/20 PHP
PHP中通过getopt解析GNU C风格命令行选项
2019/11/18 PHP
js 加载时自动调整图片大小
2008/05/28 Javascript
JavaScript 基础知识 被自己遗忘的
2009/10/15 Javascript
jQuery 1.5最新版本的改进细节分析
2011/01/19 Javascript
分别用marquee和div+js实现首尾相连循环滚动效果,仅3行代码
2011/09/21 Javascript
浅析JQuery获取和设置Select选项的常用方法总结
2013/07/04 Javascript
如何使用jQuery Draggable和Droppable实现拖拽功能
2013/07/05 Javascript
浅谈javascript控制HTML5的全屏操控,浏览器兼容的问题
2016/10/10 Javascript
jQuery使用DataTable实现删除数据后重新加载功能
2017/02/27 Javascript
JavaScript截屏功能的实现代码
2017/07/28 Javascript
javaScript把其它类型转换为Number类型
2019/10/13 Javascript
javaScript实现一个队列的方法
2020/07/14 Javascript
OpenLayers3实现测量功能
2020/09/25 Javascript
Python爬取网易云音乐上评论火爆的歌曲
2017/01/19 Python
Python实现好友全头像的拼接实例(推荐)
2017/06/24 Python
浅谈python 里面的单下划线与双下划线的区别
2017/12/01 Python
pandas条件组合筛选和按范围筛选的示例代码
2019/08/26 Python
Python实现CNN的多通道输入实例
2020/01/17 Python
Python collections模块的使用方法
2020/10/09 Python
美国庭院家具购物网站:AlphaMarts
2019/04/10 全球购物
网络安全类面试题
2015/08/01 面试题
什么是servlet
2012/05/08 面试题
环境科学专业大学生自荐信格式
2013/09/21 职场文书
企业宣传方案
2014/03/04 职场文书
竞选劳动委员演讲稿
2014/04/28 职场文书
个人授权委托书样本
2014/09/13 职场文书
幼儿园中班教师个人工作总结
2015/02/06 职场文书
未中标通知书
2015/04/17 职场文书