Я сделал это в своем инструменте MetaMake. Вот рецепт:
- Если индекс пуст, добавьте корневой каталог в индекс с отметкой времени == dir.lastModified () - 1.
- Найти все каталоги в индексе
- Сравните временную метку каталога в индексе с меткой из файловой системы. Это быстрая операция, поскольку у вас есть полный путь (не требуется сканирование всех файлов / каталогов в дереве).
- Если временная метка изменилась, у вас есть изменения в этом каталоге. Пересканируйте его и обновите индекс.
- Если на этом шаге вы обнаружите отсутствующие каталоги, удалите поддерево из индекса
- Если вы столкнулись с существующим каталогом, игнорируйте его (будет проверено на шаге 2)
- Если вы столкнулись с новым каталогом, добавьте его с отметкой времени == dir.lastModified () - 1. Убедитесь, что это рассматривается на шаге 2.
Это позволит вам эффективно замечать новые и удаленные файлы. Так как на шаге 2 вы сканируете только известные пути, это будет очень эффективно. Файловые системы плохо перечисляют все записи в каталоге, но они быстры, когда вы знаете точное имя.
Недостаток: Вы не заметите измененные файлы. Таким образом, если вы редактируете файл, это не отразится на изменении каталога. Если вам также нужна эта информация, вам придется повторить приведенный выше алгоритм для файловых узлов в вашем индексе. На этот раз вы можете игнорировать новые / удаленные файлы, потому что они уже были обновлены во время запуска по каталогам.
[ПРАВИТЬ] Зак упомянул, что отметок времени недостаточно. Мой ответ: просто нет другого способа сделать это. Понятие «размер» совершенно не определено для каталогов и изменений от реализации к реализации. Нет API, в котором вы можете зарегистрироваться «Я хочу получать уведомления о любых изменениях, вносимых в файловую систему». Существуют API-интерфейсы, которые работают, когда ваше приложение работает, но если оно останавливает или пропускает событие, значит, вы не синхронизированы.
Если файловая система удаленная, дела обстоят хуже, потому что все виды сетевых проблем могут привести к потере синхронизации. Поэтому, хотя мое решение может быть не на 100% идеальным и водонепроницаемым, оно будет работать для всех, кроме самого сложного исключительного случая. И это единственное решение, которое зашло так далеко.
Теперь существует единственное приложение, которое хотело бы сохранить временную метку каталога после внесения изменений: вирус или червь. Это явно нарушит мой алгоритм, но при этом он не предназначен для защиты от вирусной инфекции. Если вы хотите защититься от этого, вы должны использовать совершенно другой подход.
Единственный другой способ добиться того, чего хочет Зак, - это создать новую файловую систему, которая постоянно хранит эту информацию где-нибудь, продавать ее Microsoft и ждать несколько лет (вероятно, 10 или более), пока все не будут ее использовать.