8

以下のコードを実行すると、ide、TextEditor.app、または vim のいずれかを使用して tmp.txt を手動で編集および保存した場合にのみ、監視がトリガーされます。

書き込みストリームまたは手動のシェル出力リダイレクト (echo "test" > /path/to/tmp.txt" と入力) の方法によるものではありません。

ただし、ディレクトリ名ではなくファイル自体を監視すると、機能します。

var fs, Path, file, watchPath, w;

fs = require('fs' );
Path = require('path');
file = __dirname + '/tmp.txt';
watchPath = Path.dirname(file); // changing this to just file makes it trigger

w = fs.watch ( watchPath, function (e,f) {
    console.log("will not get here by itself");
    w.close();
});
fs.writeFileSync(file,"test","utf-8");

fs.createWriteStream(file, {
    flags:'w',
    mode: 0777
} )
.end('the_date="'+new Date+'";' ); // another method fails as well

setTimeout (function () {
    fs.writeFileSync(file,"test","utf-8");
},500); // as does this one
// child_process exec and spawn fail the same way with or without timeout

質問は次のとおりです。なぜですか?ノードスクリプトからプログラムでこのイベントをトリガーする方法は?

ありがとう!

4

3 に答える 3

11

問題は、ファイルではなくディレクトリを監視するように要求したことです。

シェルのリダイレクトなどによってファイルが変更されても、ディレクトリは更新されません。この場合、ファイルは開かれ、変更され、閉じられます。ディレクトリは変更されません。変更されるのはファイルのみです。

テキスト エディタを使用してファイルを変更する場合、システム コールの通常のバックグラウンド セットは次のようになります。

fd = open("foo.new")
write(fd, new foo contents)
unlink("foo")
rename("foo.new", "foo")

このように、fooファイルは完全に古いファイルまたは完全に新しいファイルであり、新しい内容の「部分ファイル」が存在することはありません。名前の変更操作によってディレクトリ変更されるため、ディレクトリ ウォッチがトリガーされます。

于 2012-05-26T00:39:24.377 に答える
11

ファイルの内容の変更はディレクトリの変更ではないため、トリガーされません。

内部では、少なくとも 0.6 の時点で、Mac の fs.watch は kqueue を使用しており、kqueue ファイル システム通知のかなり薄いラッパーです。したがって、本当に詳細を理解したい場合は、kqueue や inode などを理解する必要があります。

しかし、「子供たちに嘘をつく」という簡単な説明が必要な場合: ユーザーが「ファイル」と考えるものは、実際には 2 つの別個のものです。実際のファイルと、実際のファイルを指すディレクトリ エントリです。これにより、ハード リンクや、削除した後でも読み書きできるファイルなどを保持できます。

通常、既存のファイルに書き込みを行っても、ディレクトリ エントリは変更されないため、ディレクトリを監視しているユーザーには変更が表示されません。そのため、 echo >tmp.txt がトリガーされません。

ただし、たとえば、新しい一時ファイルを作成してから古いファイルに移動すると、ディレクトリ エントリが変更されます (古いファイルではなく新しいファイルへのポインタになります)。そのため、通知されます。そのため、TextEditor.app がトリガーされます。

于 2012-05-26T00:39:50.820 に答える
4

上記の答えは妥当なように見えますが、完全に正確ではありません。「名前の変更」だけでなく、ファイルの変更についてディレクトリをリッスンできることは、実際には非常に便利な機能です。この機能は、少なくともWindowsでは期待どおりに機能すると思います。また、ノード0.9.2では、この機能をサポートするFSEvents APIに変更されたため、Macでも機能します。

バージョン0.9.2(不安定)

于 2012-10-22T12:48:59.820 に答える