In Node.js, is it possible to indicate where the viewed file was moved?

fs.watch contains only two possible types of events: 'rename' and 'change' . Both renaming a file (for example, using mv ) and deleting it (for example, using rm ) cause fs.watch report a 'rename' event.

After moving the file, fs.watch will continue to report events from it (unless you explicitly close FSWatcher ). When this happens, I would like to know where the file has moved.

Is there a way to do this without touching every file in the system to see when the 'change' event occurs?

+7
source share
2 answers

This seems impossible until node implements an interface for retrieving file names from a file descriptor (so you can just save fd and get the name from there on rename ), or reliably return the path / file name from FSWatcher events.

A workaround would be to create a temporary hard link to the target file via fs.link , after which you can get the file even after the changes, although you cannot get its new name.

Interestingly, EventMachine has the same problem: http://eventmachine.rubyforge.org/EventMachine/FileWatch.html#M000291

+2
source

I think you will need to look at the source stat of the file and see the inode , which is the file identifier. If the file does not move from one partition / file system / disk to another (which would actually be a copy-then-delete-original operation), then the inode will be the same.

Unfortunately, there is usually no inode lookup table to get a new name / location. You will need to systematically search for the whole system, which may not be so bad if you first look at likely places. or if you can only search for a limited area.

You can use a temporary hard link (Riccardoโ€™s idea) to determine if it is deleted instead of moving. The number of link counts will change from 1 to 2 when creating a hard link, and will change from 2 to 1 when a copy of your temporary hard link is deleted. If it is deleted, you do not need to look for a place for the file.

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

If you want to reduce latency, you may have an SQL database that you already know inode for. For example, /folder/filea and /folder/fileb both exist with different inode s. When fileb moves to filec , you do not need stat filea to look for inode , because you already looked at it earlier. This logic should significantly reduce the number of stat commands. However, if filea is deleted and fileb moved to filea , this dramatic method of shrinking will not find any results, in which case you will have to go back to looking for the entire working directory.

You still have the opportunity to ensure that the OS folders, such as /etc or /dev . are used only as a last resort. What you may never have to look for, assuming that you can detect the deletion using a temporary hard link.

How big is your work area? Do you know that a file will always move from one place to another within a specific working folder? Additional information about your problematic environment will be helpful.

+1
source

All Articles