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
这是我的使用错误还是......?
答案 0 :(得分:39)
fs.watch
api:
答案 1 :(得分:16)
我通过以下方式考虑到这一点:
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
}
}
答案 2 :(得分:13)
我建议使用chokidar
(https://github.com/paulmillr/chokidar),这比fs.watch
要好得多:
评论其README.md:
Node.js fs.watch
:
rename
。 Node.js fs.watchFile
:
答案 3 :(得分:9)
如果您需要查看文件以进行更改,那么您可以查看我的小型图书馆on-file-change。它检查已触发的change
事件之间的文件sha1哈希值。
解释为什么我们有多个被解雇的事件:
在某些情况下,您可能会注意到单个创建事件会生成由组件处理的多个Created事件。例如,如果使用FileSystemWatcher组件来监视目录中新文件的创建,然后使用记事本创建文件进行测试,即使只创建了一个文件,也可能会看到生成两个Created事件。这是因为Notepad在写入过程中执行多个文件系统操作。记事本批量写入磁盘,创建文件的内容,然后创建文件属性。其他应用程序可以以相同的方式执行。由于FileSystemWatcher监视操作系统活动,因此将拾取这些应用程序触发的所有事件。
答案 4 :(得分:1)
首先是更改,第二个是重命名
我们可以从侦听器功能
中发挥作用function(event, filename) {
}
侦听器回调获取两个参数(event,filename)。 event是'rename'或'change',filename是触发事件的文件的名称。
// rm sourcefile targetfile
fs.watch( sourcefile_dir , function(event, targetfile)){
console.log( targetfile, 'is', event)
}
当一个源文件被重命名为targetfile时,它会将三个事件称为事实
null is rename // sourcefile not exist again
targetfile is rename
targetfile is change
请注意,如果你想抓住所有这三个evnet,请观看源文件的目录
答案 5 :(得分:1)
我是第一次处理这个问题,所以到目前为止所有答案都可能比我的解决方案更好,但是没有一个是100%适合我的情况所以我想出了一些略有不同的东西 - 我使用XOR操作来翻转0到1之间的整数,有效地跟踪和忽略文件上的每个第二个事件:
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建议的观看文件列表,因为我只看一个文件。 JanŚwięcki的解决方案似乎有点矫枉过正,因为我正在低功耗环境中处理极短且简单的文件。最后,Bernado的回答让我有些紧张 - 如果它在我完成第一次处理之前到达它只会忽略第二次更新,我无法处理那种不确定性。如果有人发现自己处于这种非常具体的情况,那么我使用的方法可能有一些优点吗?如果有任何重大错误,请让我知道/编辑这个答案,但到目前为止似乎运作良好?
注意:显然,此强烈假设您每次实际更改都会获得2个事件。显然,我仔细测试了这个假设,并了解了它的局限性。到目前为止,我已经确认:
touch
触发 2次更新 >
输出重定向(覆盖文件内容)会触发 2次更新 >>
追加有时会触发1次更新! * 我可以想到不同行为的完美原因,但我们不需要知道为什么正在发生的事情来计划它 - 我只想强调你要检查在你自己的环境和你自己的用例(duh)的背景下自己,而不是相信互联网上一个自认为白痴的人。话虽这么说,采取预防措施,到目前为止我并没有任何奇怪。
* 完全披露,我实际上并不知道为什么会发生这种情况,但我们已经处理了watch()函数的不可预测行为,那么更多的不确定性呢?对于在家中跟随的人来说,更快速地附加到文件似乎会导致它停止双重更新但老实说,我真的不知道,并且我对这个解决方案的行为感到满意,在实际情况下它会使用,这是一个单行文件,将以最快的速度每秒更新两次(更换内容)。
答案 6 :(得分:1)
我个人喜欢使用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);
};
来阻止在检查某些内容时运行代码块,因此,这是我的方法:
{{1}}
您可以随意使用此示例来简化代码。 NOT 可能比使用其他人的模块更好,但效果非常好!
答案 7 :(得分:0)
我有时会看到Watch事件的多次注册,导致Watch事件多次触发。 我通过保留一个观察文件列表来解决它,并避免在文件已经在列表中时注册事件:
var watchfiles = {};
function initwatch(fn, callback) {
if watchlist[fn] {
watchlist[fn] = true;
fs.watch(fn).on('change', callback);
}
}
...
答案 8 :(得分:0)
相似/同样的问题。当它们被添加到目录中时,我需要对图像做一些事情。以下是我处理双击的方法:
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;
});
它将忽略第二次触发,直到完成与新文件有关的操作。
答案 9 :(得分:0)
像其他人一样,答案说......这有很多麻烦,但我可以这样处理:
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
}
}
});
希望我可以帮助你...
答案 10 :(得分:0)
最简单的解决方案:
spotlightLondon
答案 11 :(得分:0)
我正在使用puppeteer下载文件,一旦保存了文件,我将自动发送电子邮件。由于上述问题,我注意到我正在发送2封电子邮件。我通过使用process.exit()
停止应用程序并使用pm2自动启动来解决了。在代码中使用标志并不能挽救我。
如果将来有人遇到此问题,则也可以使用此解决方案。退出程序并使用监视工具自动重新启动。
答案 12 :(得分:0)
这是我的简单解决方案。每次都运行良好。
// Update obj as file updates
obj = JSON.parse(fs.readFileSync('./file.json', 'utf-8'));
fs.watch('./file.json', () => {
const data = JSON.parse(fs.readFileSync('./file.json', 'utf-8') || '{}');
if(Object.entries(data).length > 0) { // This checks fs.watch() isn't false-firing
obj = data;
console.log('File actually changed: ', obj)
}
});