Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Node.js, is it possible to tell where a watched file was moved to?

fs.watch provides only two possible event types: 'rename' and 'change'. Both renaming a file (e.g. using mv) and deleting it (e.g. using rm) cause fs.watch to report a 'rename' event.

After a file is moved, fs.watch will continue to report events from it (unless you explicitly close the FSWatcher). When that happens, I'd like to know where the file has moved to.

Is there any way to do this, short of touching every file on the system in turn to see when a 'change' event is fired?

like image 965
Trevor Burnham Avatar asked Nov 15 '11 22:11

Trevor Burnham


People also ask

Is it possible to watch a directory in Node JS?

Node.js makes both file and directory watching easy -- but it's a bit more difficult than you may think. Simply put: Node.js' watching features aren't consistent or performant yet, which the documentation admits.

How do I read a file in Node JS?

The simplest way to read a file in Node.js is to use the fs.readFile () method, passing it the file path, encoding and a callback function that will be called with the file data (and the error): Alternatively, you can use the synchronous version fs.readFileSync ():

What is node watch file?

Watch Files and Directories with Node.js. Watching a file or directory for changes is an important part of automation. We all enjoy using our favorite CSS preprocessor's "watch" feature -- we can still refresh the page and see our changes as though we were simply writing in pure CSS.

What is the use of FS watch Node JS?

Node.js fs.watch () Method Last Updated : 29 Jul, 2020 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.


2 Answers

This looks impossible until node either implements an interface to get file names from a file descriptor (so you could just keep a fd and get the name from there on rename), or gives back the path/filename reliably along the FSWatcher events.

A workaround to this would be to create a temporary hard link to the target file via fs.link , then you can get at the file even after changes, though you won't be able to retrieve it's new name.

It's interesting that EventMachine has the same issue: http://eventmachine.rubyforge.org/EventMachine/FileWatch.html#M000291

like image 127
Ricardo Tomasi Avatar answered Oct 12 '22 12:10

Ricardo Tomasi


I guess you would have to look at the original stat of the file and see the inode which is the identifier of the file. If the file did not move from one partition/filesystem/drive to another (which would actually have to be a copy-then-delete-original operation), then the inode would be the same.

Unfortunately, there is usually no lookup table of inodes to get their new name/location. You would have to systematically search the whole system, which might not be so bad assuming you can look at likely places first. or if you can search a limited area only.

You can use a temporary hard link (Ricardo's idea) to detect if it is deleted instead of moved. The number of links counter would change from 1 to 2 when you create your hard link, and would change from 2 back to 1 when the counterpart to your temporary hard link is deleted. If it is deleted, you have no need to look for the file's destination.

If there are only, say a few thousand files in this area, the solution here should work very well, if there are more, depending on your system, it might work, but there might be a delay.

If you wish to decrease the delay, you can have an SQL database of files that you already know the inodes for. For example, /folder/filea and /folder/fileb Both exist with different inodes. When fileb is moved to filec, you have no need to stat filea looking for the inode because you already looked it up previously. This logic should dramatically reduce the number of stat commands necessary. However, if filea is deleted and fileb is moved into fileas place, this dramatic reduction method would find no results, in which case you would have to fall back to searching the entire working directory.

You do still have the option of ensuring that OS folders like /etc or /dev. are only used as a last resort. Which you may never have to search, assuming you can detect deletion using the temporary hard link.

How big is your working area? Do you know for certain whether the file will always be moved from one place to another within a certain working folder? Additional details on your problem environment would be helpful.

like image 29
700 Software Avatar answered Oct 12 '22 11:10

700 Software