[size=18][/size]Boa noite a todos!!!
Estou precisando saber como faço para forçar o fechamento de um arquivo para que eu possa excluir o arquivo.
Segue abaixo o código que criei para varrer arquivos em um diretório e excluir, só que se o arquivo estiver aberto ele não é excluído. Como faço para forçar o fechamento?
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class cTeste {
public static void main(String[] args) throws FileNotFoundException,
IOException {
File arq2 = new File ("c:/testeapaga/Criação de usuário OPERADOR.pdf" );
arq2.delete();
try{
FileReader reader = new FileReader(arq2);
BufferedReader leitor = new BufferedReader(reader);
System.out.println("apagou");
leitor.close();
}
catch (IOException e){
System.out.println(e.toString());
System.exit(5);
}
}
public void deleteFile2(File file){
if (file.listFiles() != null)
{
File[] files = file.listFiles();
for (int i = 0; i < files.length; i ++){
if (files[i].isFile()){
//file.delete();
System.out.println(" file: " + files[i].toString());
//files[i].close;
files[i].delete();
}else{
System.out.println( "pasta: "+ files[i].toString());
cTeste objApaga = new cTeste();
objApaga.deleteFile2(files[i]);
}
//this.deleteFile(files[i]);
}
}
}
}
se eu nao me engano em arquivo texto e arquivo binario, o metodo eh, nome da variavel que tem o arquivo .close();
acho que este é o metodo!!!
O método .close apenas finaliza a sua conexão com o arquivo.
Que eu saiba não há como excluir um arquivo aberto, pois o próprio Sistema Operacional NÃO permite. Caso você precise, deverá procurar algo a nível de Sistema Operacional, e não Java.
Um arquivo aberto não pode ser excluído no Windows, a menos que você feche fisicamente seu “handle” (existem ferramentas que fazem isso, mas não são de uso muito seguro e só devem ser usadas como último recurso - veja o site SysInternals da Microsoft); no Linux/Unix, ele pode até ser excluído (ou seja, não aparece mais na listagem de arquivos apresentada por ls -l) mas o arquivo permanece aberto e ocupando espaço no disco.
Quando o arquivo for fechado, então não haverá mais referências para ele e só assim o arquivo irá ser realmente removido do disco.
De qualquer maneira, o jeito clássico de fechar um arquivo é com finally:
BufferedReader br = null;
try {
br = new BufferedReader (new FileReader ("teste.txt"));
for (String linha = br.readLine(); linha != null; linha = br.readLine()) {
...
}
} catch (......) {
} finally {
// Note que o close do BufferedReader já fecha o FileReader que foi encapsulado
// dentro do BufferedReader. Portanto é necessário dar apenas o close mais externo.
if (br != null) try { br.close(); } catch (IOException ex) { ex.printStackTrace(); }
}
Boa noite Thingol,
Desde já obrigado por sua resposta, mas tenho uma dúvida em relação a ela.
Desta forma como você propôs é possível fechar arquivos que não tenho sido abertos pelo java, ou seja que possam estar em uso por outro aplicativo?
É porque estou fazendo um scritpt para apagar arquivos em uma pasta temporária, e por vezes estes arquivos são utilizados pelo sistema e não são fechados, mas não tem mais utilidade, por isso preciso forçar o fechamento e posteriormente deletá-los.
Eu pensei em procurar alguma API do Windows que fizesse isso mas não encontrei ainda.
Um abraço.
Não tem como matar a thread que tá usando o arquivo e depois excluir ele? Não sei se é a melhor maneira de fazer, mas é uma que acho que poderia funcionar…
Dá um System.gc() para forçar a coleta de lixo e limpar o handle do arquivo. Tenta excluir depois disso.
Não; fechar arquivos abertos por outro aplicativo é uma coisa que exige ter as permissões e chamar as APIs adequadas, e pode dar problemas no funcionamento do próprio Windows. Não é uma boa coisa para se fazer.
[quote]
É porque estou fazendo um scritpt para apagar arquivos em uma pasta temporária, e por vezes estes arquivos são utilizados pelo sistema e não são fechados, mas não tem mais utilidade, por isso preciso forçar o fechamento e posteriormente deletá-los.[/quote]
O que normalmente se faz é o seguinte (muitos instaladores fazem isso):
Chama-se uma API do Windows chamada MoveFileEx. Com o parâmetro adequado (NULL e MOVEFILE_DELAY_UNTIL_REBOOT) você pode solicitar ao Windows (escrevendo uma entrada no Registry) que ao reiniciar o Windows ele apague o tal arquivo que ficou “bloqueado” por alguma outra aplicação.
[color=darkblue]Boa noite a todos!!![/color]
Obrigado pela ajuda. Vou tratar os arquivos abertos como exceção e posteriormente chamar a API do Windows para forçar o fechamento dos arquivos.
Um grande abraço!!!
[quote=alan-java][color=darkblue]Boa noite a todos!!![/color]
Obrigado pela ajuda. Vou tratar os arquivos abertos como exceção e posteriormente chamar a API do Windows para forçar o fechamento dos arquivos.
Um grande abraço!!![/quote]
Já tentou as outras soluções postadas??
kra, acredito que só tem como fechar se você tentar finalizar o processo no Windows (mas tirar toda a portabilidade do Java, pois se você rodar isso em um Mac por exemplo, vai dar um baita erro).
Usei o System.gc() e funfou perfeitamente da seguinte forma:
public boolean setExcluir(HashMap mapa,String pDirName){
BaseDados bd = new BaseDados();
int idAnexo=Integer.parseInt(mapa.get("idAnexo").toString());
try {
Anexo anexo = AnexoIEX.getInstance().getOne(idAnexo);
File file = new File(pDirName+"/"+anexo.getNome());
File filethumbs = new File(pDirName+"/thumbs/"+anexo.getNome());
System.gc();//só adicionei o chamado, sem ele não deletava nem com reza...
if(file.exists()){
file.delete();
}
if(filethumbs.exists()){
filethumbs.delete();
}
String Inserir =
" delete from tb_anexos where id_anexo = " +Integer.parseInt(mapa.get("idAnexo").toString());
if (bd.setInserir(Inserir)){
return true;
}
else{
return false;
}
} catch (Exception e) {
System.out.println("setExcluir "+e);
return false;
}
}