Eu tenho um processo Java que abre um arquivo usando um FileReader. Como posso impedir que outro processo (Java) abra esse arquivo ou, pelo menos, notifique esse segundo processo que o arquivo já está aberto? Isso faz automaticamente o segundo processo obter uma exceção se o arquivo estiver aberto (o que resolve meu problema) ou eu tenho que abri-lo explicitamente no primeiro processo com algum tipo de sinalizador ou argumento?
Esclarecer:
Eu tenho um aplicativo Java que lista uma pasta e abre cada arquivo na listagem para processá-lo. Ele processa cada arquivo após o outro. O processamento de cada arquivo consiste em lê-lo e fazer alguns cálculos com base no conteúdo, e leva cerca de 2 minutos. Eu também tenho outro aplicativo Java que faz a mesma coisa, mas que grava no arquivo. O que eu quero é poder executar esses aplicativos ao mesmo tempo, para que o cenário seja assim. O ReadApp lista a pasta e localiza os arquivos A, B, C. Ele abre o arquivo A e inicia a leitura. O WriteApp lista a pasta e localiza os arquivos A, B, C. Ele abre o arquivo A, vê que está aberto (por uma exceção ou de qualquer maneira) e vai para o arquivo B. ReadApp termina o arquivo A e continua para B. Ele vê que está está aberto e continua até C. É crucial que o WriteApp não Não escreva enquanto o ReadApp está lendo o mesmo arquivo ou vice-versa. São processos diferentes.
Respostas:
FileChannel.lock é provavelmente o que você deseja.
(Isenção de responsabilidade: código não compilado e certamente não testado.)
Observe a seção intitulada "dependências da plataforma" no documento da API para FileLock .
fonte
FileOutputStream
).FileOutputStream
não vai ser muito útil para umReader
.NonWritableChannelException
, porquelock()
tenta adquirir um bloqueio exclusivo, mas isso requer acesso de gravação. Se você tiver um fluxo de entrada , poderá usar olock(0L, Long.MAX_VALUE, false)
que adquire um bloqueio compartilhado e requer apenas um acesso de leitura. Você também pode usar um modoRandomAccessFile
aberto de leitura / gravação se desejar um bloqueio exclusivo durante a leitura ... mas isso proibiria os leitores simultâneos.lock(0L, Long.MAX_VALUE, true)
, nãolock(0L, Long.MAX_VALUE, false)
. o último argumento existeboolean shared
docs.oracle.com/javase/8/docs/api/java/nio/channels/…Não use as classes no
java.io
pacote, use ojava.nio
pacote. Este último tem umaFileLock
classe. Você pode aplicar um bloqueio aFileChannel
.fonte
Se você pode usar o Java NIO ( JDK 1.4 ou superior ), acho que está procurando
java.nio.channels.FileChannel.lock()
FileChannel.lock ()
fonte
File locks are held on behalf of the entire Java virtual machine. They are not suitable for controlling access to a file by multiple threads within the same virtual machine
use java.nio.channels.FileLock em conjunto com java.nio.channels.FileChannel
fonte
Pode não ser o que você está procurando, mas no interesse de encontrar um problema de outro ângulo ....
Esses dois processos Java podem querer acessar o mesmo arquivo no mesmo aplicativo? Talvez você possa filtrar todo o acesso ao arquivo através de um único método sincronizado (ou, melhor ainda, usando o JSR-166 )? Dessa forma, você pode controlar o acesso ao arquivo e, talvez, até solicitações de acesso na fila.
fonte
Use um RandomAccessFile, obtenha o canal e chame lock (). O canal fornecido pelos fluxos de entrada ou saída não possui privilégios suficientes para bloquear corretamente. Certifique-se de chamar unlock () no bloco final (fechar o arquivo não necessariamente libera o bloqueio).
fonte
Abaixo está um código de trecho de amostra para bloquear um arquivo até que seu processo seja concluído pela JVM.
fonte