Одновременная запись файла в Java на Windows

Что происходит, когда вы одновременно открываете два (или более) FileOutputStreams в одном и том же файле?

Java API говорит это:

В частности, некоторые платформы позволяют открывать файл для записи только одним FileOutputStream (или другим объектом записи файла) за раз.

Я предполагаю, что Windows не такая платформа, потому что у меня есть два потока, которые читают какой-то большой файл (каждый по-своему), а затем записывают его в один и тот же выходной файл. Исключение не выдается, файл создан и, кажется, содержит фрагменты из обоих входных файлов.

Дополнительные вопросы:

  • Это правда и для Unix?
  • И поскольку я хочу, чтобы поведение было таким же (на самом деле я хочу, чтобы один поток записал правильно, а другой был предупрежден о конфликте), как я могу определить, что файл уже открыт для записи?

4 ответа

Решение

Не существует надежного кроссплатформенного способа пассивного уведомления, когда файл имеет другого записывающего устройства, т. Е. Вызвать исключение, если файл уже открыт для записи. Однако есть пара методов, которые помогут вам активно проверить это.

Если файл использует несколько процессов (которые могут быть смесью Java и не-Java), используйте FileLock, Ключ к успешному использованию блокировок файлов - помнить, что они только "рекомендательные". Блокировка гарантированно будет видимой, если вы проверите ее, но она не помешает вам что-то сделать с файлом, если вы забудете. Все процессы, которые обращаются к файлу, должны быть разработаны для использования протокола блокировки.

Если с файлом работает один процесс Java, вы можете использовать инструменты параллелизма, встроенные в Java, чтобы сделать это безопасно. Вам нужна карта, видимая всем потокам, которая связывает каждое имя файла с соответствующим экземпляром блокировки. Ответы на связанный вопрос могут быть легко адаптированы, чтобы сделать это с File объекты или канонические пути к файлам. Объект блокировки может быть FileOutputStream какая-то обертка вокруг ручья или ReentrantReadWriteLock ,

Я бы с осторожностью позволил ОС определять статус файла для вас (так как это зависит от ОС). Если у вас есть общий ресурс, я бы ограничил доступ к нему, используя блокировку повторного входа

Использование этой блокировки означает, что один поток может получить ресурс (файл) и записать в него. Следующий поток может проверить, удерживается ли эта блокировка другим потоком, и / или блокировать неопределенно, пока первый поток не освободит ее.

Windows (я думаю) ограничит два процесса записи в один и тот же файл. Я не верю, что Unix сделал бы то же самое.

Если два потока, о которых вы говорите, находятся в одной и той же JVM, то у вас может быть где-то логическая переменная, к которой обращаются оба потока.

Unix позволяет одновременно записывать в один и тот же файл.

Вы не должны пытаться записывать в один и тот же файл более одного раза. Если у вас есть недостатки дизайна.

Другие вопросы по тегам