Подтвердить что ты не робот

Параллельная запись файла в Java на Windows

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

API Java говорит следующее:

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

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

Боковые вопросы:

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

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

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