fs.watch( 'example.xml', function ( curr, prev ) {
// on file change we can read the new xml
fs.readFile( 'example.xml','utf8', function ( err, data ) {
if ( err ) throw err;
console.dir(data);
console.log('Done');
});
});
出力:
- 一部のデータ
- 完了X 1
- 一部のデータ
- 完了X 2
それは私の使用法の誤りか..?
fs.watch
api:
私は以下を行うことでこれを考慮に入れます:
var fsTimeout
fs.watch('file.js', function(e) {
if (!fsTimeout) {
console.log('file.js %s event', e)
fsTimeout = setTimeout(function() { fsTimeout=null }, 5000) // give 5 seconds for multiple events
}
}
fs.watch
よりも優れているchokidar
( https://github.com/paulmillr/chokidar )を使用することをお勧めします。
README.mdへのコメント:
Node.js fs.watch
:
rename
として発行します。Node.js fs.watchFile
:
ファイルの変更を監視する必要がある場合は、私の小さなライブラリ on-file-change を確認してください。発生したchange
イベント間のファイルsha1ハッシュをチェックします。
複数の発生したイベントがある理由の説明:
特定の状況では、単一の作成イベントが、コンポーネントによって処理される複数のCreatedイベントを生成することに気付く場合があります。たとえば、FileSystemWatcherコンポーネントを使用してディレクトリ内の新しいファイルの作成を監視し、メモ帳を使用してそれをテストしてファイルを作成すると、1つのファイルしか作成されていなくても、2つのCreatedイベントが生成されることがあります。これは、メモ帳が書き込みプロセス中に複数のファイルシステムアクションを実行するためです。メモ帳は、ファイルのコンテンツを作成してからファイル属性を作成するバッチでディスクに書き込みます。他のアプリケーションも同じ方法で実行できます。 FileSystemWatcherはオペレーティングシステムのアクティビティを監視するため、これらのアプリケーションが起動するすべてのイベントが取得されます。
私はこの問題を初めて扱っているので、これまでのすべての回答はおそらく私の解決策よりも優れていますが、それらのどれも私のケースに100%適していなかったため、少し異なるものを思いつきました-私は= XOR 0と1の間の整数を反転する操作は、ファイルの2番目のイベントを効果的に追跡し、無視します。
var targetFile = "./watchThis.txt";
var flippyBit = 0;
fs.watch(targetFile, {persistent: true}, function(event, filename) {
if (event == 'change'){
if (!flippyBit) {
var data = fs.readFile(targetFile, "utf8", function(error, data) {
gotUpdate(data);
})
} else {
console.log("Doing nothing thanks to flippybit.");
}
flipBit(); // call flipBit() function
}
});
// Whatever we want to do when we see a change
function gotUpdate(data) {
console.log("Got some fresh data:");
console.log(data);
}
// Toggling this gives us the "every second update" functionality
function flipBit() {
flippyBit = flippyBit ^ 1;
}
時間に関連する関数(jwymanmの回答など)を使用したくありませんでした。これは、監視しているファイルが仮想的に頻繁に正当な更新を取得する可能性があるためです。また、Erik Pが提案するように、監視しているファイルのリストを使用したくありませんでした。これは、1つのファイルしか監視していないためです。 JanŚwięckiのソリューションは、低電力環境で非常に短くシンプルなファイルに取り組んでいるため、やり過ぎのように思えました。最後に、ベルナドの答えは少し緊張しました。最初の処理が完了する前に2番目の更新が到着した場合にのみ無視され、そのような不確実性を処理できません。この非常に具体的なシナリオで誰かが自分を見つけたとしたら、私が使用したアプローチにはいくつかのメリットがあるかもしれませんか?それに大きな問題がある場合は、私にこの回答を知らせてください/編集してください。
注:明らかにこれstronglyは、実際の変更ごとに正確に2つのイベントを取得すると想定しています。私は明らかにこの仮定を慎重にテストし、その限界を学びました。これまでのところ、私はそれを確認しました:
touch
トリガー2更新>
(ファイル内容の上書き)トリガーによる出力リダイレクト2更新>>
を介して追加すると、1つの更新がトリガーされることがあります! *異なる動作の完全に良い理由を考えることができますが、なぜ何かが起こっているのかを知る必要はありません–私はただしたかっただけです自分の環境と自分のユースケースのコンテキストで自分自身をチェックしたい(duh)ことを強調し、インターネット上の自白の馬鹿を信用しないようにします。とは言っても、予防策を講じて、今のところ奇妙なことはありません。
*完全な開示、これがなぜ起こっているのか実際にはわかりませんが、watch()関数で予測できない動作をすでに処理しているので、もう少し不確実なことは何ですか?自宅でフォローしている人にとっては、ファイルへのより迅速な追加により、ファイルの二重更新が停止するように見えますが、正直なところ、私にはよくわかりません。実際の場合、このソリューションの動作には満足しています。これは、最速で毎秒2回のように更新される(コンテンツが置き換えられる)1行のファイルです。
私は個人的にreturn
を使用して、何かをチェックするときにコードのブロックが実行されるのを防ぐのが好きなので、ここに私の方法があります:
var watching = false;
fs.watch('./file.txt', () => {
if(watching) return;
watching = true;
// do something
// the timeout is to prevent the script to run twice with short functions
// the delay can be longer to disable the function for a set time
setTimeout(() => {
watching = false;
}, 100);
};
この例を使用して、コードを簡略化してください。 [〜#〜]ない[〜#〜]他のモジュールを使用するよりも良いかもしれませんが、それはかなりうまくいきます!
最初は変更で、2番目は名前の変更です
リスナー関数との違いを作ることができます
function(event, filename) {
}
リスナーコールバックは2つの引数(イベント、ファイル名)を取得します。 eventは 'rename'または 'change'のいずれかで、filenameはイベントをトリガーしたファイルの名前です。
// rm sourcefile targetfile
fs.watch( sourcefile_dir , function(event, targetfile)){
console.log( targetfile, 'is', event)
}
ソースファイルの名前がターゲットファイルに変更されると、3つのイベントが実際に呼び出されます
null is rename // sourcefile not exist again
targetfile is rename
targetfile is change
これら3つのevnetをすべてキャッチしたい場合は、sourcefileのディレクトリを確認してください。
ときどき、Watchイベントの登録が何度も発生し、Watchイベントが数回発生します。監視ファイルのリストを保持し、ファイルがすでにリストにある場合はイベントを登録しないことで解決しました。
var watchfiles = {};
function initwatch(fn, callback) {
if watchlist[fn] {
watchlist[fn] = true;
fs.watch(fn).on('change', callback);
}
}
…….
最も簡単な解決策:
const watch = (path, opt, fn) => {
var lock = false
fs.watch(path, opt, function () {
if (!lock) {
lock = true
fn()
setTimeout(() => lock = false, 1000)
}
})
}
watch('/path', { interval: 500 }, function () {
// ...
})
他の回答が言うように...これは多くの問題を抱えましたが、私はこのようにこれに対処することができます:
var folder = "/folder/path/";
var active = true; // flag control
fs.watch(folder, function (event, filename) {
if(event === 'rename' && active) { //you can remove this "check" event
active = false;
// ... its just an example
for (var i = 0; i < 100; i++) {
console.log(i);
}
// ... other stuffs and delete the file
if(!active){
try {
fs.unlinkSync(folder + filename);
} catch(err) {
console.log(err);
}
active = true
}
}
});
お手伝いできれば幸いです...
私は人形遣いでファイルをダウンロードしていて、ファイルが保存されると、自動メールを送信していました。上記の問題が原因で、2つのメールを送信していることに気付きました。 process.exit()
を使用してアプリケーションを停止し、pm2で自動起動することで解決しました。コードでフラグを使用しても、私は救われませんでした。
将来この問題が発生した場合は、このソリューションを使用することもできます。プログラムを終了し、監視ツールで自動的に再起動します。
類似/同じ問題。ディレクトリに追加されたとき、私は画像でいくつかのことをする必要がありました。これが私が二重発砲に対処した方法です:
var fs = require('fs');
var working = false;
fs.watch('directory', function (event, filename) {
if (filename && event == 'change' && active == false) {
active = true;
//do stuff to the new file added
active = false;
});
新しいファイルの処理が完了するまで、2回目の起動は無視されます。