Node.js 检测文件系统的mtime分辨率

Node.js 检测文件系统的mtime分辨率,node.js,filesystems,filemtime,Node.js,Filesystems,Filemtime,如何从Node.js中找出系统的mtime分辨率 我为什么这么问 在Node.js中,fs.watch有时会发出重复的change事件。为了避免重复操作,通常会使用这样的代码(来自CoffeeScript的coffee实用程序): 问题是:在OSX下,由于底层的HFS+文件系统,mtime的分辨率只有1秒。也就是说,mtime.getTime()值的形式如下 1322068921000 因此,每当两个更改在彼此的1秒内发生时,第二个更改就有可能不会影响文件的mtime。多亏了stats.siz

如何从Node.js中找出系统的mtime分辨率

我为什么这么问 在Node.js中,
fs.watch
有时会发出重复的
change
事件。为了避免重复操作,通常会使用这样的代码(来自CoffeeScript的
coffee
实用程序):

问题是:在OSX下,由于底层的HFS+文件系统,
mtime
的分辨率只有1秒。也就是说,
mtime.getTime()
值的形式如下

1322068921000
因此,每当两个更改在彼此的1秒内发生时,第二个更改就有可能不会影响文件的
mtime
。多亏了
stats.size
检查,如果第二次更改对文件大小没有影响,这才是一个问题。尽管如此,这还是一个问题


可靠的解决方案是按mtime间隔对
更改
事件进行“去抖动”;i、 e.在OS X下,当发生
更改时,我会等待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中的其他文件系统也有同样的问题(1s时间戳粒度),以及旧的用于Windows的FAT32

一种黑客解决方案是在读取文件(或发送文件事件)之前将文件的mtime设置回一秒钟。这样,如果在同一粒度窗口内发生另一次修改(本例中为1s),则新的mtime将不同,您将能够检测到修改


如果没有其他应用程序使用该文件的mtime,这应该可以正常工作,否则它可能会干扰它们的操作。这是一个解决方法,真的,不是一个合适的解决方案。尽管如此,我还是发现它在某些场景中很有用,例如,对我的Java代码进行自动测试(测试会很快连续修改文件,比实际使用中自然发生的要多).

我真的希望找到一个不涉及I/O的解决方案。这是一个库。也许你可以在库初始化时扫描模块目录,节点无论如何都会扫描,需要并加载它,因此很少的额外I/O调用不会产生巨大的差异。我如何确保模块目录将包含一组具有多个不同
mtime
s的文件?您不能确定,但如果文件系统支持毫秒粒度,则所有文件都不太可能具有精确秒的mtime。对,只要有几个文件是在不同的时间创建的。但是我怎样才能找到这样的目录呢?
files.forEach(function(filename) {
    sum += fs.statSync(filename).mtime % 1000;
});

if (sum == 0) {
   // supports only 1 second resolution
}