检测文件系统的mtime分辨率
如何从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()
值的forms
1322068921000
所以每当两秒钟之内发生两次更改,就有可能第二次更改不会影响文件的mtime
。 由于stats.size
检查,这只是一个问题,如果第二个更改没有影响文件的大小。 不过,这是一个问题。
一个可靠的解决scheme是通过间隔时间“去抖” change
事件; 即在OS X下,当发生change
时,我会等待1秒钟来执行操作(从而将所有可能具有相同mtime
更改事件组合在一起)。 但是我希望在每个文件系统下尽可能缩短时间,而不是采用最大的共同点。
迭代某个目录中的所有文件(如/ tmp)并执行如下操作
files.forEach(function(filename) { sum += fs.statSync(filename).mtime % 1000; }); if (sum == 0) { // supports only 1 second resolution }
有点哈克,我知道。
编写一些Java代码时,我遇到了同样的问题。 这个问题超越了Node.js,因为大多数语言在处理文件时都有类似的API(并且都受到文件系统特定约束的限制)。 Linux中的其他文件系统具有相同的问题(1秒时间戳粒度),以及Windows的旧FAT32。
一个诡秘的解决scheme是在读取文件(或发送文件事件)之前,将文件的mtime设置回一秒钟。 这样,如果在相同的粒度窗口(在这种情况下是1秒)内发生另一个修改,则新的mtime将会不同,并且您将能够检测到修改。
如果没有其他应用程序正在使用该文件的mtime,这应该工作得很好,否则可能会干扰他们的操作。 这是一个解决方法,真的,不是一个合适的解决scheme。 尽pipe如此,我发现它在某些情况下很有用,例如,我的Java代码的自动化testing(testing快速连续修改文件,比现实世界使用中自然发生的更多)。