如何从Node.js中找出系统的mtime分辨率?
在Node.js中,fs.watch
有时会发出重复的change
个事件。为了避免采取冗余操作,通常使用这样的代码(来自CoffeeScript的coffee
实用程序):
if event is 'change'
fs.stat source, (err, stats) ->
throw err if err
return if stats.size is prevStats.size and
stats.mtime.getTime() is prevStats.mtime.getTime()
prevStats = stats
...
问题在于:在OS X下,由于底层HFS +文件系统,mtime
的分辨率仅为1秒。也就是说,mtime.getTime()
值的格式为
1322068921000
因此,只要彼此在1秒内发生两次更改,第二次更改就有可能不会影响文件的mtime
。感谢stats.size
检查,如果第二次更改对文件大小没有影响,这只是一个问题。不过,这是一个问题。
一个可靠的解决方案是在mtime间隔内“去抖动”change
事件;即在OS X下,当change
发生时,我会等待1秒钟对其进行操作(从而将可能具有相同mtime
的所有更改事件分组在一起)。但是我希望在每个文件系统下延迟事件的最短时间,而不是采用最大的共同点。
答案 0 :(得分:1)
迭代某些目录中的所有文件(例如/ tmp)并执行类似这样的操作
files.forEach(function(filename) {
sum += fs.statSync(filename).mtime % 1000;
});
if (sum == 0) {
// supports only 1 second resolution
}
有点hacky,我知道。
答案 1 :(得分:1)
编写一些Java代码时遇到了同样的问题。这个问题超越了Node.js,因为大多数语言在处理文件时都有类似的API(并且都受到文件系统特定约束的限制)。 Linux中的其他文件系统具有相同的问题(1s时间戳粒度),以及旧的FAT32 for Windows。
一个hacky解决方案是在读取文件(或发送文件事件)之前将文件的mtime实际设置为一秒钟。这样,如果在同一粒度窗口内发生了另一次修改(在这种情况下为1s),则新的mtime将不同,并且您将能够检测到修改。
如果没有其他应用程序正在使用该文件的mtime,这应该可以正常工作,否则它可能会很好地干扰他们的操作。这是一个变通方法的黑客,真的,不是一个合适的解决方案。尽管如此,我发现它在某些情况下很有用,例如,我的Java代码的自动化测试(测试快速连续地修改文件,比实际使用中自然发生的更多)。