Node.js 实现文件监听
目录
Node.js,实现文件监听,可以使用 fs.watch 和 fs.watchFile 。
也可以通过第三方库 chokidar 来实现。
fs.watch
官网例子:
fs.watch('somedir', (eventType, filename) => {
console.log(`event type is: ${eventType}`);
if (filename) {
console.log(`filename provided: ${filename}`);
} else {
console.log('filename not provided');
}
});
fs.watch
的不支持子文件夹的侦听,而且在很多情况下会侦听到两次事件。
chokidar
安装什么的就不介绍了,参考 官方文档 。
例子:
class ContentPackWatcher {
constructor(robot, options = {awaitWriteFinish: true}) {
let dirPath = `${process.env.HUBOT_ENTERPRISE_PACKAGES_DIR}/*.zip`;
this.watcher = Chokidar.watch(dirPath, options);
this.watcher
.on('add', this.addFileListener.bind(this))
.on('addDir', this.addDirectoryListener.bind(this))
.on('change', this.fileChangeListener.bind(this))
.on('unlink', this.fileDeleteListener.bind(this))
.on('unlinkDir', this.directoryDeleteListener.bind(this))
.on('error', this.errorListener.bind(this))
.on('ready', this.readyListener.bind(this));
}
getWatched() {
return this.watcher.getWatched();
}
stopWatch(paths) {
this.watcher.unwatch(paths);
}
readyListener() {
logger.info('Initial scan complete. Ready for changes.');
}
errorListener(error) {
logger.error('Error happened', error)
}
//add new file
addFileListener(filePath, stats) {
if (stats.size > 0) {
logger.info(`File ${filePath} has been added, size: ${stats.size}.`);
}
}
//add new directory
addDirectoryListener(dirPath) {
logger.info(`Directory ${dirPath} has been added.`);
}
//watch file change
fileChangeListener(filePath, stats) {
if (stats.size > 0) {
logger.info(`File ${filePath} has been changed, size: ${stats.size}.`);
}
}
//watch file delete
fileDeleteListener(filePath) {
logger.info(`File ${filePath} has been removed.`);
}
//watch directory delete
directoryDeleteListener(dirPath) {
logger.info(`Directory ${dirPath} has been removed.`);
}
}
API
chokidar.watch(paths, [options])
paths
: 可以是一个字符串数组或一个字符串。options
: 对象。persistent
: 默认true
,进程是否持续监听文件,如果设置为false
,当使用 fsevents 监听时,ready
之后不会触发任何监听事件。ignored
: 忽略某些文件的监听,ignoreInitial
: 默认false
,如果设置为false
,在初始化 chokidar 实例时,如果监听到匹配的文件也会被触发add/addDir
事件。followSymlinks
: 默认true
,如果设置为false
,只看符号链接本身的变化。cwd
: 监听的路径的base
目录。disableGlobbing
: 默认false
,如果设置为 true,那么传递给.watch()
和add()
的字符串被视为文字路径名,即使它们看起来就像 globs。usePolling
: 默认false
,是否使用fs.watchFile
(backed by polling), 或者fs.watch
,如果轮询导致CPU占用过高,可以设置 为false
。它通常需要设置true
当通过网络监听文件时和非标准的情况下。在 OS X 上设置为true
,会覆盖useFsEvents
,也可以设 置CHOKIDAR_USEPOLLING
环境变量来覆盖它。Polling-specific
设置(只在usePolling: true
是有效)interval
:(default: 100) 文件系统轮询时间间隔,也可以通过设置环境变量CHOKIDAR_INTERVAL
来覆盖它。binaryInterval
:(default: 300) 二进制文件系统轮询时间间隔。
useFsEvents
:(default: true on OS X)当 fsevents 的监听接口可用时,是否启用。当显式地设置为true
,fsevents 取代usePolling
。 在 OS X 上设置为false
时,usePolling: true
变为默认。alwaysStat
: 默认false
,如果add
,addDir
,change
事件依赖fs.Stats
对象(callback的第二个参数),设置为true
时, 可以确保传入这个对象,尽管它不是可用的。depth
: 默认undefined
,遍历子目录的层级。awaitWriteFinish
: 默认false
,默认情况下,文件第一次出现在磁盘上,文件被写完之前,就会触发add
事件。此外,在某些情况下会触 发change
事件,在一些情况下,特别是监听大文件,需要在等待写操作完成以后回复一个文件创建或者修改。设置为true
,会检查文件大小,直到文件在 设置的时间内(stabilityThreshold)不再改变,才会触发add
或者change
事件。设置适当的时间依赖系统和硬件。awaitWriteFinish
可以是 一个对象,包含下面的属性:stabilityThreshold
: (default: 2000)单位毫秒,等待文件大小不再改变的时间,在设置时间之后触发事件。pollInterval
: (default: 100),检查文件大小的时间间隔。
ignorePermissionErrors
: 默认false
,忽略没有权限操作文件的error
。
事件
chokidar
可以通过 on
方法监听到下面的事件:
- add, 文件添加
- addDir, 文件夹添加
- change, 文件变化
- unlink, 文件删除
- unlinkDir, 文件夹删除
- ready
- raw
- error
除了 ready
,raw
,error
这三个事件,其他事件触发都可以拿到文件路径。
方法
.add(path / paths)
: 添加监听文件。参数可以是一个字符串数组或一个字符串。.on(event, callback)
: 监听事件,除了ready
,raw
,error
这三个事件,其他事件的callback
函数的第一个参数是文件路径。.unwatch(path / paths)
: 停止监听某个文件。参数可以是一个字符串数组或一个字符串。.close()
: 删除所有文件监听。.getWatched()
: 返回一个包含所有被监听的文件的对象。