检测文件系统的mtime分辨率

时间:2011-11-23 18:01:18

标签: node.js filesystems filemtime

如何从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的所有更改事件分组在一起)。但是我希望在每个文件系统下延迟事件的最短时间,而不是采用最大的共同点。

2 个答案:

答案 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代码的自动化测试(测试快速连续地修改文件,比实际使用中自然发生的更多)。