В Java есть ли способ прочитать файл, когда этот файл заблокирован другим потоком?

#java #file-io #filelock

#java #file-io #блокировка файла

Вопрос:

Итак, я использовал следующее, чтобы создать блокировку для файла, чтобы я мог редактировать его исключительно:

  File file = new File(filename);
 channel = new RandomAccessFile(file, "rw").getChannel();
 lock = channel.tryLock();
  

Теперь у меня есть 2-й поток, который хочет получить доступ к тому же файлу — просто для чтения, а не для редактирования. Как мне это сделать? Прямо сейчас 2-й поток выдаст исключение ввода-вывода и сообщит мне, что файл заблокирован.

Это выполнимо? Есть предложения? Спасибо

Ответ №1:

Вы могли бы попробовать запросить общую блокировку, используя версию tryLock с тремя аргументами.

Вот соответствующий javadoc: http://download.oracle.com/javase/1.4.2/docs/api/java/nio/channels/FileChannel.html#tryLock(long, long, boolean)

В принципе, вместо того, чтобы делать lock=channel.tryLock() , вы бы сделали lock = channel.trylock(0, Long.MAX_VALUE, true)

Кроме того, вы должны быть осторожны с блокировкой файлов в java. Хотя вы можете гарантировать, что блокировки будут вести себя как ожидалось в JVM, вы не обязательно можете быть уверены, что они будут вести себя как ожидалось в нескольких процессах.

Ответ №2:

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

Ответ №3:

Возможно, это помогает!

 public abstract FileLock tryLock(long position,
                                 long size,
                                 boolean shared)
                         throws IOException
  

Пытается получить блокировку в заданной области файла этого канала.

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

Область, указанная параметрами position и size, необязательно должна содержаться внутри фактического базового файла или даже перекрывать его. Области блокировки имеют фиксированный размер; если заблокированная область изначально содержит конец файла, а файл выходит за пределы области, то новая часть файла не будет охвачена блокировкой. Если ожидается, что размер файла будет увеличиваться и требуется блокировка всего файла, то должна быть заблокирована область, начинающаяся с нуля и не меньшая ожидаемого максимального размера файла. tryLock() Метод с нулевым аргументом просто блокирует область определенного размера Long.MAX_VALUE .

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

Блокировки файлов выполняются от имени всей виртуальной машины Java. Они не подходят для управления доступом к файлу несколькими потоками в пределах одной виртуальной машины.

Параметры: position — позиция, с которой должна начинаться заблокированная область; должен быть неотрицательный size — размер заблокированной области; должен быть неотрицательным, а сумма position size должна быть неотрицательной общей — true для запроса общей блокировки, false для запроса эксклюзивной блокировки Возвращает: Объект блокировки, представляющий недавно полученную блокировку, или null, если блокировку не удалось получить, потому что другая программа содержит перекрывающуюся блокировку, выдает: IllegalArgumentException — Если предварительные условия для параметров не выполняются ClosedChannelException — Если этот канал закрыт OverlappingFileLockException — Если блокировка, перекрывающая запрошенную область, уже удерживается этой виртуальной машиной Java или если другой поток уже заблокирован в этом методе и пытается заблокировать перекрывающуюся область того же файла IOException — Если возникает какая-либо другая ошибка ввода-вывода См. Также: lock() , lock(long,long,boolean) , tryLock()