node.js 如何監(jiān)視文件變化
fs.FSWatcher
fs.FSWatcher類(lèi) 繼承了 EventEmitter,用于監(jiān)視文件變化,調(diào)用 fs.watch 后返回一個(gè) fs.FSWatcher 實(shí)例,每當(dāng)指定監(jiān)視的文件被修改時(shí),實(shí)例會(huì)觸發(fā)事件調(diào)用回調(diào)函數(shù)
fs.watch('./tmp', (eventType, filename) => { if (filename) { console.log(filename); } });
fs.watch()
fs.watch(filename[, options][, listener])
監(jiān)視文件變化,返回 fs.FSWatcher 實(shí)例
1.filename:文件或文件夾路徑
2.options
- encoding
- recursive:默認(rèn)值 false,應(yīng)該監(jiān)視所有子目錄,還是僅監(jiān)視當(dāng)前目錄,僅在 macOS 和 Windows 上支持
- persistent:默認(rèn)值 true,指示如果文件已正被監(jiān)視,進(jìn)程是否應(yīng)繼續(xù)運(yùn)行
- listener(eventType, filename):文件變化回調(diào)函數(shù)
eventType 主要是 rename
和 change
,在大多數(shù)平臺(tái)上,文件在目錄中出現(xiàn)或消失時(shí)觸發(fā) 'rename' 事件,在 Windows 上,如果監(jiān)視的目錄被移動(dòng)或重命名,則不會(huì)觸發(fā)任何事件,當(dāng)監(jiān)視的目錄被刪除時(shí),則報(bào)告 EPERM
錯(cuò)誤
fs.watch('./', { recursive: true }, (eventType, filename) => { console.log(eventType, filename); });
fs.watchFile()
fs.watchFile(filename[, options], listener)
用于監(jiān)視文件變化
1.filename
2.options
- biginit:默認(rèn)值 false,指定回調(diào) stat 中的數(shù)值是否為 biginit 類(lèi)型
- persistent:默認(rèn)值 true,當(dāng)文件正在被監(jiān)視時(shí),進(jìn)程是否應(yīng)該繼續(xù)運(yùn)行
- interval:默認(rèn)值 5007,用來(lái)指定輪詢(xún)頻率(ms)
3.listener(currentStats, previousStats):listener 有兩個(gè)參數(shù),當(dāng)前的 stat 對(duì)象和之前的 stat 對(duì)象
要在修改文件時(shí)收到通知,則需要比較 curr.mtime
和 prev.mtime
const fs = require('fs'); fs.watchFile('./test.txt', { interval: 100 }, (curr, prev) => { console.log('當(dāng)前的最近修改時(shí)間是: ' + curr.mtime); console.log('之前的最近修改時(shí)間是: ' + 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()
因?yàn)?fs.watchFile() 使用輪訓(xùn)方式檢測(cè)文件變化,如果不設(shè)置 interval
或者設(shè)置較高的值會(huì)發(fā)現(xiàn)文件變化的監(jiān)視有延遲
而 fs.watch() 監(jiān)聽(tīng)操作系統(tǒng)提供的事件,而且可以監(jiān)視目錄變化,使用 fs.watch() 比 fs.watchFile() 更高效,平常應(yīng)盡可能使用 fs.watch() 代替 fs.watchFile()
當(dāng)然 fs.watch() 依賴(lài)操作系統(tǒng)的實(shí)現(xiàn),在不同平臺(tái)上表現(xiàn)會(huì)有差異
- Linux 操作系統(tǒng)使用 inotify
- 在 macOS 系統(tǒng)使用 FSEvents
- 在 windows 系統(tǒng)使用 ReadDirectoryChangesW
fs.unwatchFile
fs.unwatchFile(filename[, listener])
停止監(jiān)視 filename 的變化,如果指定了 listener,則僅移除此特定監(jiān)聽(tīng)器,否則將移除所有監(jiān)聽(tīng)器,從而停止監(jiān)視 filename
fs.unwatchFile('./test.txt');
社區(qū)選擇
fs.watchFile() 性能問(wèn)題,fs.watch() 平臺(tái)不一致等兩個(gè)方法都有不盡如人意的地方
Node.js fs.watch
:
MacOS 有時(shí)候不提供 filename
在部分場(chǎng)景不觸發(fā)修改事件(MacOS Sublime)
經(jīng)常一次修改兩次觸發(fā)事件
大部分文件變化 eventType 都是 rename.
未提供簡(jiǎn)單的監(jiān)視文件樹(shù)方式
Node.js fs.watchFile
:
事件處理問(wèn)題和 fs.watch 一樣爛
沒(méi)有嵌套監(jiān)聽(tīng)
CPU 消耗大
https://www.npmjs.com/package/chokidar
日常在監(jiān)視文件變化可以選擇社區(qū)的優(yōu)秀方案
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 如何監(jiān)視文件變化的詳細(xì)內(nèi)容,更多關(guān)于node.js 監(jiān)視文件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
從零學(xué)習(xí)node.js之簡(jiǎn)易的網(wǎng)絡(luò)爬蟲(chóng)(四)
簡(jiǎn)單的爬蟲(chóng)實(shí)現(xiàn)原理很簡(jiǎn)單:發(fā)送http請(qǐng)求至目標(biāo)地址獲取HTML頁(yè)面數(shù)據(jù),然后從獲取來(lái)的頁(yè)面數(shù)據(jù)中提取需要的數(shù)據(jù)保存。下面這篇文章主要介紹了利用node.js實(shí)現(xiàn)簡(jiǎn)易的網(wǎng)絡(luò)爬蟲(chóng)的相關(guān)資料,需要的朋友可以參考下。2017-02-02nodejs遍歷文件夾下并操作HTML/CSS/JS/PNG/JPG的方法
這篇文章主要介紹了nodejs遍歷文件夾下并操作HTML/CSS/JS/PNG/JPG的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-11-11Node.js中path.join()優(yōu)勢(shì)例舉分析
在本篇文章里小編給大家整理的是一篇關(guān)于Node.js中path.join()優(yōu)勢(shì)例舉分析,有興趣的朋友們可以學(xué)習(xí)下。2021-08-08在Node.js中實(shí)現(xiàn)獲取用戶(hù)頻道信息的功能
在構(gòu)建社交或視頻分享平臺(tái)時(shí),允許用戶(hù)查看其他用戶(hù)的頻道信息是一個(gè)基本需求,本文將介紹如何在Node.js應(yīng)用中,使用Express框架和Mongoose庫(kù)來(lái)實(shí)現(xiàn)這一功能,文中有相關(guān)的代碼示例供大家參考,需要的朋友可以參考下2024-04-04