Pergunta

Eu tenho um processo que será chamado com bastante frequência de Cron para ler um arquivo que possui certos comandos relacionados a mover. Meu processo precisa ler e gravar neste arquivo de dados - e mantê -lo bloqueado para impedir que outros processos o tocem durante esse período. Um processo completamente separado pode ser executado por um usuário em (potencial) gravar/anexar a esse mesmo arquivo de dados. Quero que esses dois processos joguem bem e acessem o arquivo apenas um de cada vez.

O Nio Filelock parecia ser o que eu precisava (sem escrever meus próprios arquivos do tipo semáforo), mas estou tendo problemas para travá -lo para ler. Eu posso travar e escrever muito bem, mas ao tentar criar bloqueio ao ler, recebo uma não -WritableChannException. É possível bloquear um arquivo para leitura? Parece que um RandomAccessFile está mais próximo do que eu preciso, mas não vejo como implementar isso.

Aqui está o código que falha:

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());
          ...

A exceção é lançada na linha do 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)

Olhando para os javadocs, diz

Exceção desmarcada jogada quando uma tentativa é feita para escrever para um canal que não foi aberto originalmente para escrever.

Mas eu não preciso necessariamente escrever para isso. Quando tento criar um FileOutpustream, etc. Para escrever fins, é feliz até que eu tente abrir um FileInputStream no mesmo arquivo.

Foi útil?

Solução

(a) Você está ciente de que o bloqueio do arquivo não impedirá que outros processos o tocem, a menos que eles também usem bloqueios?
(b) Você precisa travar através de um canal gravável. Pegue a fechadura por meio de um RandomAccessFile no modo "RW" e depois abra seu FileInputStream. Certifique -se de fechar os dois!

Outras dicas

Seria melhor se você criasse o bloqueio usando tryLock(0L, Long.MAX_VALUE, true).

Isso cria uma trava compartilhada, que é a coisa certa a fazer para ler.

tryLock() é uma abreviação para tryLock(0L, Long.MAX_VALUE, false), ou seja, solicita um bloqueio exclusivo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top