【问题标题】:Detect file changes in node.js via watchFile通过 watchFile 检测 node.js 中的文件更改
【发布时间】:2011-04-17 21:58:17
【问题描述】:

我想检测文件的变化,如果文件发生变化,我会使用 child_process 执行 scp 命令将文件复制到服务器。我查阅了 node.js 文档,fs.watchFile 函数似乎是做什么的我想做,但是当我尝试它时,不知怎的,它并没有像我预期的那样工作。使用了以下代码:

var fs = require('fs');                                                                        

console.log("Watching .bash_profile");

fs.watchFile('/home/test/.bash_profile', function(curr,prev) {
    console.log("current mtime: " +curr.mtime);
    console.log("previous mtime: "+prev.mtime);
    if (curr.mtime == prev.mtime) {
        console.log("mtime equal");
    } else {
        console.log("mtime not equal");
    }   
});

使用上面的代码,如果我访问被监视的文件,回调函数被执行,它会输出相同的mtime,并且总是输出“mtime not equal”(我只访问文件)。输出:

Watching .bash_profile
current mtime: Mon Sep 27 2010 18:41:27 GMT+0100 (BST)
previous mtime: Mon Sep 27 2010 18:41:27 GMT+0100 (BST)
mtime not equal

当两个 mtime 相同时,任何人都知道为什么 if 语句失败(也尝试使用 === 识别检查,但仍然得到相同的输出)?

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    如果mtime 属性是Date 对象,那么它们永远不会相等。在 JavaScript 中,两个单独的对象只有当它们实际上是同一个对象时才相等(变量指向同一个内存实例)

    obj1 = new Date(2010,09,27);
    obj2 = new Date(2010,09,27);
    obj3 = obj1; // Objects are passed BY REFERENCE!
    
    obj1 != obj2; // true, different object instances
    obj1 == obj3; // true, two variable pointers are set for the same object
    obj2 != obj3; // true, different object instances
    

    要检查这两个日期值是否相同,请使用

    curr.mtime.getTime() == prev.mtime.getTime();
    

    (我实际上不确定是否是这种情况,因为我没有检查 watchFile 是否输出 Date 对象或字符串,但从您的描述来看,确实是这样)

    【讨论】:

    • 谢谢,我没有意识到mtime属性是一个对象(我以为它们是字符串对象:(我使用typeof curr.mtime,它返回对象,在javascript中有没有办法找出什么样的对象?。在您给出的示例中,我认为 obj1 == obj2,因为您只更改了相等性检查,当他们进行身份检查时只有 false obj1 ==== obj2。
    • 您可以像这样使用运算符instanceofvar d = new Date(); if(d instanceof Date == true)alert(1); 或者获取文本对象类型使用var d = new Date(); Object.prototype.toString.call(d); // "[object Date]"
    • 我注意到的一件事是,如果我执行以下操作: var i = 10; if (i instanceof Number) alert(1); if 语句永远不会为真(typeof i => "number" and Object.prototype.toString.call(i) => "[object Number]",但是如果我将 i 声明为:var i = Number(10),它可以工作。有人知道它背后的原因吗?
    • 10 不是对象,而是文字,new Number(10) 是对象 - instanceof 仅适用于对象。如果您与typeof 核对,则typeof 10 == "number"typeof new Number(10) == "object"。因此,new Number(10) 是一个对象,instanceof 运算符开始工作。
    【解决方案2】:

    快速而讨厌的解决方案。 如果您没有根据之前或之后()进行日期比较,而只是比较日期字符串,只需对每个日期字符串执行快速 toString()。

     if (curr.mtime.toString() == prev.mtime.toString()) 
    

    【讨论】:

      【解决方案3】:

      遗憾的是正确的方法是

      if (+curr.mtime === +prev.mtime) {}
      

      + 将 Date 对象强制为 int,即 unixtime。

      【讨论】:

        【解决方案4】:

        对于“聪明”的人:

        if (curr.mtime - prev.mtime) {
            // file changed
        }
        

        【讨论】:

        • 您可能正在编写伪代码,但只是为了澄清一下,因为这些是日期对象而不是整数值:+curr.mtime - +prev.mtime
        • @DirkSmaverson 减法将日期对象强制转换为数字,就像一元加号运算符一样,所以它是等价的。
        【解决方案5】:

        为了简化事情,您可以使用Watchr 来获取有用的事件(仅在文件实际更改时才会触发change 事件)。它还支持查看整个目录树:)

        【讨论】:

          【解决方案6】:

          我们使用 chokidar 进行文件监视,即使在运行 windows 文件系统的 centos 机器(在 windows 机器上运行的 vagrant virtualbox centos)的可疑上下文中也能正常工作

          https://github.com/paulmillr/chokidar

          【讨论】:

          • 这对我有用,监控 Mac OSX 上的文件何时更新。
          猜你喜欢
          • 1970-01-01
          • 2018-12-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-10
          • 1970-01-01
          相关资源
          最近更新 更多