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 (eg using mv ) and deleting it (eg 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?


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


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 inode s 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 inode s for. For example, /folder/filea and /folder/fileb Both exist with different inode s. 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 filea s 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.

链接地址: http://www.djcxy.com/p/10006.html

上一篇: UIViewController报告为响应addChildViewController:在iOS 4上

下一篇: 在Node.js中,是否可以告诉观察文件被移动到哪里?