Node.js 检测文件系统的mtime分辨率
如何从Node.js中找出系统的mtime分辨率 我为什么这么问 在Node.js中,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
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
}