Вопрос

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

Это было полезно?

Решение

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top