В Node.js можно ли определить, куда был перемещен просматриваемый файл? - PullRequest
9 голосов
/ 16 ноября 2011

fs.watch предоставляет только два возможных типа событий: 'rename' и 'change'. Как переименование файла (например, с использованием mv), так и удаление его (например, с использованием rm) заставляют fs.watch сообщить о событии 'rename'.

После перемещения файла fs.watch продолжит сообщать о событиях из него (если вы явно не закроете FSWatcher ). Когда это произойдет, я бы хотел знать, куда переместился файл.

Есть ли способ сделать это, кроме касания каждого файла в очереди, чтобы увидеть, когда происходит событие 'change'?

Ответы [ 2 ]

3 голосов
/ 20 ноября 2011

Это выглядит невозможным, пока узел не реализует интерфейс для получения имен файлов из файлового дескриптора (так что вы можете просто сохранить fd и получить имя оттуда на rename), или пока не вернете путь / имя файла надежно поСобытия FSWatcher.

Обходной путь может заключаться в создании временной жесткой ссылки на целевой файл через fs.link, после чего вы сможете получить файл даже после изменений, хотя вы не сможете получитьэто новое имя.

Интересно, что EventMachine имеет ту же проблему: http://eventmachine.rubyforge.org/EventMachine/FileWatch.html#M000291

1 голос
/ 21 ноября 2011

Полагаю, вам нужно посмотреть исходную статистику файла и увидеть inode, который является идентификатором файла. Если файл не перемещался с одного раздела / файловой системы / диска на другой (что на самом деле должно было быть операцией копирования-затем-удаления-оригинала), то inode будет таким же.

К сожалению, обычно нет справочной таблицы inode s, чтобы получить их новое имя / местоположение. Вам придется систематически обыскивать всю систему, что может быть не так уж и плохо, если вы сначала посмотрите на вероятные места. или если вы можете искать только в ограниченной области.

Вы можете использовать временную жесткую ссылку (идея Рикардо), чтобы определить, была ли она удалена, а не перемещена. Счетчик количества ссылок изменится с 1 на 2 при создании жесткой ссылки, и изменится с 2 на 1 при удалении аналога вашей временной жесткой ссылки. Если он удален, вам не нужно искать место назначения файла.

Если в этой области есть, скажем, несколько тысяч файлов, решение здесь должно работать очень хорошо, если их больше, в зависимости от вашей системы, оно может работать, но может быть задержка.

Если вы хотите уменьшить задержку, у вас может быть база данных SQL с файлами, для которых вы уже знаете inode s. Например, /folder/filea и /folder/fileb Оба существуют с разными inode с. Когда fileb перемещается в filec, вам не нужно stat filea искать inode, потому что вы уже искали его ранее. Эта логика должна значительно сократить количество необходимых stat команд. Однако, если filea удалено и fileb перемещено на место filea, этот метод резкого сокращения не даст результатов, и в этом случае вам придется вернуться к поиску по всему рабочему каталогу.

У вас все еще есть возможность убедиться, что такие папки ОС, как /etc или /dev. используются только в качестве крайней меры. Который вам, возможно, никогда не придется искать, при условии, что вы можете обнаружить удаление, используя временную жесткую ссылку.

Насколько велика ваша рабочая зона? Вы точно знаете, будет ли файл всегда перемещаться из одного места в другое в пределах определенной рабочей папки? Дополнительные сведения о вашей проблемной среде будут полезны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...