Como descobrir qual tópico está bloqueando um arquivo em java?
-
24-09-2019 - |
Pergunta
Estou tentando excluir um arquivo com o qual outro tópico do meu programa trabalhou anteriormente.
Não consigo excluir o arquivo, mas não tenho certeza de como descobrir qual tópico pode estar usando o arquivo.
Então, como faço para descobrir qual tópico está bloqueando o arquivo em java?
Solução
Não tenho uma resposta direta (e acho que não há uma, isso é controlado no nível do OS (nativo), não no nível da JVM) e também não vejo o valor da resposta ( Você ainda não pode fechar o arquivo programaticamente depois de descobrir qual tópico é), mas acho que ainda não sabe que a incapacidade de excluir geralmente é causada quando o arquivo ainda está aberto. Isso pode acontecer quando você faz não ligar explicitamente Closeable#close()
no InputStream
, OutputStream
, Reader
ou Writer
que é construído em torno do File
em questão.
Demonstração básica:
public static void main(String[] args) throws Exception {
File file = new File("c:/test.txt"); // Precreate this test file first.
FileOutputStream output = new FileOutputStream(file); // This opens the file!
System.out.println(file.delete()); // false
output.close(); // This explicitly closes the file!
System.out.println(file.delete()); // true
}
Em outras palavras, verifique se durante todo o seu java io material, o código está corretamente fechamento os recursos após o uso. O idioma normal é fazer isso em a try-with-resources
declaração, para que você possa ter certeza de que os recursos serão liberados de qualquer maneira, mesmo em caso de um IOException
. Por exemplo
try (OutputStream output = new FileOutputStream(file)) {
// ...
}
Faça isso por algum InputStream
, OutputStream
, Reader
e Writer
, etc, quaisquer implementos AutoCloseable
, que você está abrindo você mesma (usando o new
palavra -chave).
Isso tecnicamente não é necessário em determinadas implementações, como ByteArrayOutputStream
, mas, por uma questão de clareza, apenas siga o idioma próximo em todos os lugares para evitar conceitos errôneos e refatorar-se.
Caso você ainda não esteja no Java 7 ou mais recente, use o abaixo try-finally
idioma em vez disso.
OutputStream output = null;
try {
output = new FileOutputStream(file);
// ...
} finally {
if (output != null) try { output.close(); } catch (IOException logOrIgnore) {}
}
Espero que isso ajude a acertar a causa raiz de seu problema específico.
Outras dicas
Sobre esta pergunta, também tento descobrir esta resposta e perguntar essa questão e encontre resposta:
Toda vez que o thread da JVM trava um Arquivo exclusivamente, também a JVM bloqueia alguns Objeto Jave, por exemplo, acho que no meu caso:
- Sun.nio.fs.nativebuffer
- sun.nio.ch.util $ buffercache
Então, você precisa encontrar esse objeto Java bloqueado e analisou -os e encontra qual encadeamento bloqueou seu arquivo.
Não tenho certeza de que funcione se o arquivo apenas aberto (sem bloqueado exclusivamente), mas tenho certeza de que é o trabalho se o arquivo for bloqueado exclusivamente por thread (usando java.nio.channels.filelock, java.nio.channels.filechannel e assim sobre)
Mais informações, veja essa questão