Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to watch symlink'ed files in node.js using watchFile()

Tags:

node.js

I am trying to monitor a file that is (soft) symlink'ed with node.js' watchFile() with the following code:

var fs=require('fs')
    , file= './somesymlink'
    , config= {persist:true, interval:1}; 

fs.watchFile(file, config, function(curr, prev) { 
    if((curr.mtime+'')!=(prev.mtime+'')) { 
        console.log( file+' changed'); 
    } 
});

In the above code, ./somesymlink is a (soft) symlink to /path/to/the/actual/file. When changes are made to the /path/to/the/actual/file, no event is fired. I have to replace the symlink with /path/to/the/actual/file to make it work. It seems to me that watchFile is not able to watch symlink'ed files. Of course I could make this work by using spawn+tail method but I prefer not to use that path as it would introduce more overhead.

So my question is how can I watch symlink'ed files in node.js using watchFile(). Thanks folks in advance.

like image 528
ricochen Avatar asked Feb 20 '12 16:02

ricochen


People also ask

How do I read a file path in node JS?

var fs = require('fs'), path = require('path'), filePath = path. join(__dirname, 'start. html'); fs. readFile(filePath, {encoding: 'utf-8'}, function(err,data){ if (!

What is fs watch?

The fs. watch() method is an inbuilt application programming interface of fs module which is used to continuously watch for changes in the given file or directory. It returns a fs. FSWatcher object that can be used to track the changes in the file.

Which API is used to work with a file in Nodejs?

The easiest way to write to files in Node. js is to use the fs. writeFile() API. By default, this API will replace the contents of the file if it does already exist.

Where is fs module in node JS?

The Node.js file system module allows you to work with the file system on your computer. To include the File System module, use the require() method: var fs = require('fs');


1 Answers

You could use fs.readlink:

fs.readlink(file, function(err, realFile) {
    if(!err) {
        fs.watch(realFile, ... );
    }
});

Of course, you could get fancier and write a little wrapper that can watch either the file or it's link, so you don't have to think about it.

UPDATE: Here's such a wrapper, for the future:

/** Helper for watchFile, also handling symlinks */
function watchFile(path, callback) {
    // Check if it's a link
    fs.lstat(path, function(err, stats) {
        if(err) {
            // Handle errors
            return callback(err);
        } else if(stats.isSymbolicLink()) {
            // Read symlink
            fs.readlink(path, function(err, realPath) {
                // Handle errors
                if(err) return callback(err);
                // Watch the real file
                fs.watch(realPath, callback);
            });
        } else {
            // It's not a symlink, just watch it
            fs.watch(path, callback);
        }
    });
}
like image 90
Linus Thiel Avatar answered Oct 10 '22 07:10

Linus Thiel