检测文件系统的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快速连续修改文件,比现实世界使用中自然发生的更多)。