2013-08-08 3 views
10

Документация DirectoryStream четко сказано:Итерация DirectoryStream и изменение содержимого каталога в то же время

итератора слабо согласуется. Он является потокобезопасным, но не Замораживает каталог во время итерации, поэтому он может (или не показывать) отражать обновления в каталоге, которые возникают после создания DirectoryStream .

На моей машине я выполнил простую итерацию по каталогу в режиме отладки. Перед завершением итерации я нарушил выполнение, добавил файл в повторяющийся и возобновленный каталог. Итерация не увидела дополнительный файл.

Мой вопрос: при каких обстоятельствах будет Итерация отражает обновления содержимого каталога? К сожалению, официальная документация очень расплывчата. По меньшей мере.

+2

Я не знаю, но так, как я его читал, он недетерминирован и может зависеть от ОС OS/FS и конкретных реализаций. Мое лучшее предположение, что оно будет отражать обновления, если ваш каталог находится в inode, который расположен позже в дереве, чем текущий, на который указывает итератор. Как провоцировать такое поведение я не знаю. Я уверен, что это невозможно сразу (детерминированным образом) с использованием чистой Java. –

ответ

4

Документация намеренно расплывчата. JVM должен работать на нескольких машинах разных типов: Windows и Unix-производных. Различные файловые системы имеют разные типы поведения. Вы должны (я повторяю, MUST) дизайн для наихудшего случая, если вы хотите, чтобы ваша программа надежно работала на нескольких компьютерах.

Закон наименьшего удивления предполагает, что вы должны разбить весь DirectoryStream, чтобы получить моментальный снимок (или очень близко к нему), выполнить итерацию по снимку, а затем повторно очистить поток. Затем вы можете сравнить различные версии снимков, чтобы определить изменения в базовом каталоге.

+0

Я полностью согласен с заключением, вопрос был вне академического интереса. – Vitaliy

2

Как интерфейс DirectoryStream, и поскольку эта часть NIO.2 предназначена для подключения, не ограничивайте рассмотрение внедрений, поставляемых с JDK для Linux и Windows. Было бы вполне возможно написать настраиваемую реализацию именно с этим поведением или для кластерной или распределенной реализации, чтобы иметь такое поведение как побочный эффект.

документация намеренно расплывчатым, и под POSIX, он делегирует на readdir, который also intentionally vague:

Если файл удаляется из или добавляются в каталог после последнего вызова opendir() или rewinddir (), будет ли следующий вызов readdir_r() возвращать запись для этого файла, не указывается.

Однако, если вы после этого конкретного случая, когда реализация опиралась на эту неясность, то Linux ext3 readdir and concurrent updates показывает случай, когда rsync, на ext3 файловой системы с большим объемом, появился, чтобы увидеть файлы появляются в каталоге за пределами порядок, в котором они были созданы.