开发者

Detect file changes in node.js via watchFile

开发者 https://www.devze.com 2023-01-17 15:24 出处:网络
I want to detect changes for a file, if the file changes, I will use child_process to execute a scp command to copy the file to a server.I looked up node.js documentation, the fs.watchFile function se

I want to detect changes for a file, if the file changes, I will use child_process to execute a scp command to copy the file to a server.I looked up node.js documentation, the fs.watchFile function seems do what I want to do, but when I tried it, somehow it just doesn't work as I expected. The following code were used:

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");
    }   
});

With above code, if I access the watched file, the callback function get execute, it will output the same mtime, and always output "mtime not equal" (I only accessing the file). Outputs:

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

Anybody know why the if statement failed(also tried using === identify check, but still get the same output) when the two mtime are the same?


If mtime properties are Date objects, then these can never be equal. In JavaScript two separate objects are equal ONLY if they are actually the same object (variables are pointing to the same memory instance)

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

To check if these two date values are the same, use

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

(I'm not actually sure if this is the case since I didn't check if watchFile outputs Date objects or strings but it definitely seems this way from your description)


For "clever" people:

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


Sadly the correct way is

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

The + forces the Date object to int which is unixtime.


To simplify things you can use Watchr to get useful events (will only fire the change event if a file has actually changed). It also supports watching entire directory trees :)


We use chokidar for file watching, which works even in the dubious context of a centos machine running with a windows file system (vagrant virtualbox centos running on windows machine)

https://github.com/paulmillr/chokidar


quick and nasty solution. If you are not doing a date comparison in terms of previous or after (< or >) and you are simply comparing the datestrings, just do a quick toString() on each one.

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

精彩评论

暂无评论...
验证码 换一张
取 消