监视文件系统意味着监视特定目录或文件的更改 。
文章插图
有时您可能需要持续观察特定文件或目录的更改 。出于这个原因,我们使用像 chokidar 这样的文件系统 Watcher 或内置的 NodeJs 文件系统方法 fs.watch() 。
但是我们不会使用上面的方法,让我来告诉你这样做的原因 。
fs.watch()
fs 提供了一个应用程序编程接口 (API),可连续监视文件的更改 。可以使用此方法跟踪文件更改,该方法返回一个 fs.FSWatcher 对象 。在这里阅读更多关于它的信息 fs.watch() 。
缺点:
- 这种方法不可靠,每次修改都可能在监听器中显示多个事件 。
- 将大多数更改作为重命名发出 。
- 不提供递归查看文件树的简单方法 。
- 不报告 macOS 上的文件名 。
chokidar
它是最流行的文件系统观察器,但尽管在某些情况下它可能就足够了,但它并不完美 。
优点:
- 它支持处理符号链接 。
- 它有一些内置支持,可以在执行原子写入时处理写入磁盘的临时文件,尽管在 Watcher 中忽略它们也很简单,您可以通过忽略选项忽略它们 。
- 它可以更可靠地观察网络连接的路径,尽管在观察大量文件时会导致性能问题 。
- 尽管 Watcher(一个文件系统观察程序库,我们稍后会讨论)具有更全面的测试套件并且也用于生产(例如在 Notable 中,它之前使用了 chokidar),但它经过了更多的实战测试 。
- 它需要原生依赖才能在 macOS 下进行高效的递归观察,而原生依赖可能很难使用 。
- 在 windows 下它不能有效地递归地观察,另一方面,Watcher(一个文件系统观察器库,我们将在后面讨论)是建立在 Node 的 Windows 原生递归观察能力之上的 。
- 它无法检测重命名 。
- 如果您不需要像 globbing 这样的功能,那么 chokidar 会不必要地膨胀您的应用程序包 。
- EMFILE 错误没有得到正确处理,因此如果您观看的文件足够多,chokidar 最终会放弃它们 。
【七爪源码:使用 NodeJs 观看文件系统】
Watcher
一个追求完美的文件系统观察者,没有原生依赖和可选的重命名检测支持 。
我自己使用过这个库,与其他替代方案相比,我发现它非常简单且无错误 。特征:
- 可靠:该库旨在处理处理文件系统时可能出现的所有问题,包括一些最流行的无法处理的替代方案,例如 EMFILE 错误 。
- 重命名检测:这个库可以选择性地检测文件和目录何时被重命名,这允许您在某些情况下为您的用户提供更好的体验 。
- 性能:在可用时使用本机递归监视(macOS 和 Windows),否则可以有效地手动执行 。
- 没有原生依赖:原生依赖使用起来会很痛苦,这个库使用了其中的 0 个 。
- 不臃肿:许多替代观察者附带可能无用且昂贵的功能,例如对通配的支持,这个库旨在更精简,同时仍然公开正确的抽象,让您可以根据需要使用通配 。
- TypeScript-ready:这个库是用 TypeScript 编写的,所以类型不是事后才想到的,而是随库一起提供的 。
安装:
npm install — save watcher用法:
你会像这样使用这个库:
const Wattcher = require('watcher')// Watching a single pathconst watcher = new Watcher ( '/foo/bar' );// Watching multiple pathsconst watcher = new Watcher ( ['/foo/bar', '/baz/qux'] );// Passing some optionsconst watcher = new Watcher ( '/foo/bar', { renameDetection: true } );// Passing an "all" handler directlyconst watcher = new Watcher ( '/foo/bar', {}, ( event, targetPath, targetPathNext ) => {} );// Attaching the "all" handler manuallyconst watcher = new Watcher ( '/foo/bar' );watcher.on ( 'all', ( event, targetPath, targetPathNext ) => { // This is what the library does internally when you pass it a handler directlyconsole.log ( event ); // => could be any target event: 'add', 'addDir', 'change', 'rename', 'renameDir', 'unlink' or 'unlinkDir'console.log ( targetPath ); // => the file system path where the event took place, this is always providedconsole.log ( targetPathNext ); // => the file system path "targetPath" got renamed to, this is only provided on 'rename'/'renameDir' events});// Listening to individual events manuallyconst watcher = new Watcher ( '/foo/bar' );watcher.on ( 'error', error => {console.log ( error instanceof Error ); // => true, "Error" instances are always provided on "error"});watcher.on ( 'ready', () => {// The App just finished instantiation and may soon emit some events});watcher.on ( 'close', () => {// The app just stopped watching and will not emit any further events});watcher.on ( 'all', ( event, targetPath, targetPathNext ) => {console.log ( event ); // => could be any target event: 'add', 'addDir', 'change', 'rename', 'renameDir', 'unlink' or 'unlinkDir'console.log ( targetPath ); // => the file system path where the event took place, this is always providedconsole.log ( targetPathNext ); // => the file system path "targetPath" got renamed to, this is only provided on 'rename'/'renameDir' events});watcher.on ( 'add', filePath => {console.log ( filePath ); // "filePath" just got created, or discovered by the watcher if this is an initial event});watcher.on ( 'addDir', directoryPath => {console.log ( filePath ); // "directoryPath" just got created, or discovered by the watcher if this is an initial event});watcher.on ( 'change', filePath => {console.log ( filePath ); // "filePath" just got modified});watcher.on ( 'rename', ( filePath, filePathNext ) => {console.log ( filePath, filePathNext ); // "filePath" got renamed to "filePathNext"});watcher.on ( 'renameDir', ( directoryPath, directoryPathNext ) => {console.log ( directoryPath, directoryPathNext ); // "directoryPath" got renamed to "directoryPathNext"});watcher.on ( 'unlink', filePath => {console.log ( filePath ); // "filePath" got deleted, or at least moved outside the watched tree});watcher.on ( 'unlinkDir', directoryPath => {console.log ( directoryPath ); // "directoryPath" got deleted, or at least moved outside the watched tree});// Closing the watcher once you are done with itwatcher.close ();// Updating watched roots by closing a watcher and opening an updated onewatcher.close ();watcher = new Watcher ( /* Updated options... */ );
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 3步教会你,如何把系统安装在U盘中使用!
- 文明使用公筷公勺的倡议书 文明使用公筷公勺的倡议书范文
- 体外驱虫滴剂使用方法 体外驱虫滴剂使用方法是怎样的
- 要正确合理地使用抗生素 抗生素的合理应用
- 医保怎么使用 使用医保卡的教程
- 荣事达洗衣机怎么用 如何使用荣事达洗衣机
- 医保卡怎么使用 医保卡如何使用?
- 奥马冰柜怎么使用 奥马冰柜怎么清理
- 黑客|手握《GTA6》源码与90多条视频:黑客号称要与R星谈判
- 青苔印迹怎么清理掉 青苔印迹怎么清理