2009-04-03 2 views
17

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

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

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

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

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

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

ответ

16

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

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

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

4

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

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

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

+0

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

+0

CHeck, который блокирует API. Вы сможете проверить блокировку, чтобы определить, заблокировал ли кто-то другой ее (т. Е. Не бок), а затем решить, что делать –

1

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

1

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

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

Смежные вопросы