fs.watchFileを使ってみた

More than 5 years have passed since last update.


fs.watchfileとは?

 ファイルの変更を監視して、変化が起きたらcallback関数を呼び出して教えてくれる。node以外では見たことない気がするのは、不勉強かしら。

 とにかく、そういうファイルの変更を検知するやつを作りたかったので、こまかい動きを調べてメモしました。


実験に使ったコード


watchfile.js

var fs = require('fs');

var filepath = 'message.txt';

// filepathが存在しなくても、watchFileはエラーとか出してくれないので、
// 先にfs.existsで調べておく
if (!fs.existsSync(filepath)) {
console.error('%s doesn\'t exist.', filepath);
process.exit();
}

console.log('start watch: %s', filepath);
fs.watchFile(filepath, function (curr, prev) {
// プロパティ丸ごと出力してもらう
console.dir(curr);

// 以前のmtimeと比較
console.log('the current mtime is: ' + curr.mtime);
console.log('the previous mtime was: ' + prev.mtime);
});



分かったこと


開始時に、指定したfilepathが存在しなくても、特にエラーは発生しない。


  • なので、その前に自分でfs.existsとかしてあげる必要がある。(上のコード参照)


ファイル名を変更しても、ファイルの変更とはみなされない。


  • ただし、ファイル名を変更した後も、監視は続いている。

  • chmodとかは、ちゃんと変更とみなされる。


callbackに帰ってくるのはstatオブジェクト。


  • なので、更新時間や属性などは即時でとれるが、ファイルの内容がどうなったかは、別途fs.readFileなどしないと分からない。

  • diff的な機能もなし。


対象がディレクトリでもちゃんと動く。


  • ディレクトリの中のファイルが変更された時、中にファイルが追加された時等ちゃんと検知します。

  • viで中身のファイル開いた時に、一時ファイルができるのも検知してしまうので、ちょっととまどった。(そりゃそうなんだけど)


当然、「常時待ち」のイベントをひとつ増やすことになる。


  • 例えばexpressサーバーとかは、平常時はhttpサーバーへのアクセスのみ待っている状態になっている。そこに別の常時待ちが入ってくると、なにかしら計算が狂うこともありうる。

  • 自分は、start-stop-daemonとexpressを組み合わせて使っていたので、daemon化する部分にwatchFileの開始処理も組込んでやる必要があった。


そのうち調べる


  • 監視周期1回の間に、変更が2回以上発生したら? (たぶん1回しか反応しないと思うけど)

  • 存在しないファイル名を与えてwatchを開始、その後そのファイルが追加されたら? (たぶん反応しないと思うけど)

  • unwatchも調べなきゃ……。