Java FileLock для чтения и записи - PullRequest
21 голосов
/ 16 февраля 2010

У меня есть процесс, который довольно часто вызывается из 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 для того же файла.

Ответы [ 2 ]

17 голосов
/ 16 февраля 2010

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

13 голосов
/ 29 мая 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...