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?

Problem courtesy of: Trevor Burnham

Solution

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

Solution courtesy of: Ricardo Tomasi

Discussion

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.

Discussion courtesy of: George Bailey

This recipe can be found in it’s original form on Stack Over Flow
.

稿源:Node.js Recipes - The solution to all Node problems (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 前端开发 » In Node.js, is it possible to tell where a watched file was moved to?

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录