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

Java FileLock для чтения и записи

У меня есть процесс, который будет довольно часто вызываться из cron для чтения файла, в котором есть определенные команды, связанные с перемещением. Мой процесс должен прочитать и записать в этот файл данных - и заблокировать его, чтобы другие процессы не трогали его в течение этого времени. Пользователь может автоматически выполнить отдельный процесс, чтобы (потенциально) записать/добавить в этот же файл данных. Я хочу, чтобы эти два процесса играли хорошо и только доступ к файлу по одному.

nio FileLock, казалось, был тем, что мне нужно (не написав мои собственные файлы типа семафора), но мне трудно заблокировать его для чтения. Я могу блокировать и писать просто отлично, но при попытке создать блокировку при чтении я получаю исключение NonWritableChannelException. Можно ли даже заблокировать файл для чтения? Кажется, что RandomAccessFile ближе к тому, что мне нужно, но я не вижу, как это реализовать.

Вот код, который терпит неудачу:

FileInputStream fin = new FileInputStream(f);
FileLock fl = fin.getChannel().tryLock();
if(fl != null) 
{
  System.out.println("Locked File");
  BufferedReader in = new BufferedReader(new InputStreamReader(fin));
  System.out.println(in.readLine());
          ...

Исключение выбрано в строке FileLock.

java.nio.channels.NonWritableChannelException
 at sun.nio.ch.FileChannelImpl.tryLock(Unknown Source)
 at java.nio.channels.FileChannel.tryLock(Unknown Source)
 at Mover.run(Mover.java:74)
 at java.lang.Thread.run(Unknown Source)

Глядя на JavaDocs, он говорит

Непроверенное исключение, созданное при попытке записать канал, который не был первоначально открыт для записи.

Но мне не обязательно писать. Когда я пытаюсь создать файл FileOutpuStream и т.д. Для записи, он доволен, пока не попытаюсь открыть FileInputStream в том же файле.

4b9b3361

Ответ 1

(a) Знаете ли вы, что блокировка файла не заставит другие процессы трогать его, если они также не используют блокировки?
(b) Вы должны заблокировать канал, доступный для записи. Получите блокировку через RandomAccessFile в режиме "rw", а затем откройте FileInputStream. Не забудьте закрыть оба!

Ответ 2

Было бы лучше, если бы вы создали блокировку с помощью tryLock(0L, Long.MAX_VALUE, true).

Это создает общую блокировку, которая является правильной вещью для чтения.

tryLock() является сокращением для tryLock(0L, Long.MAX_VALUE, false), т.е. запрашивает исключительную блокировку записи.