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?
importjava.io.BufferedReader;importjava.io.File;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;publicclasscTeste{publicstaticvoidmain(String[]args)throwsFileNotFoundException,IOException{Filearq2=newFile("c:/testeapaga/Criação de usuário OPERADOR.pdf");arq2.delete();try{FileReaderreader=newFileReader(arq2);BufferedReaderleitor=newBufferedReader(reader);System.out.println("apagou");leitor.close();}catch(IOExceptione){System.out.println(e.toString());System.exit(5);}}publicvoiddeleteFile2(Filefile){if(file.listFiles()!=null){File[]files=file.listFiles();for(inti=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());cTesteobjApaga=newcTeste();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!!!
Eder_Peixoto
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.
T
thingol
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.
T
thingol
De qualquer maneira, o jeito clássico de fechar um arquivo é com finally:
BufferedReaderbr=null;try{br=newBufferedReader(newFileReader("teste.txt"));for(Stringlinha=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(IOExceptionex){ex.printStackTrace();}}
alan-java
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.
Andre_Brito
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…
B
Bruno_Laturner
Dá um System.gc() para forçar a coleta de lixo e limpar o handle do arquivo. Tenta excluir depois disso.
T
thingol
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.
É 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.
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.
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!!!
B
Bruno_Laturner
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!!!
Já tentou as outras soluções postadas??
A
alexcostars
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).
fidelis_felipe
Usei o System.gc() e funfou perfeitamente da seguinte forma:
publicbooleansetExcluir(HashMapmapa,StringpDirName){BaseDadosbd=newBaseDados();intidAnexo=Integer.parseInt(mapa.get("idAnexo").toString());try{Anexoanexo=AnexoIEX.getInstance().getOne(idAnexo);Filefile=newFile(pDirName+"/"+anexo.getNome());Filefilethumbs=newFile(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();}StringInserir=" delete from tb_anexos where id_anexo = "+Integer.parseInt(mapa.get("idAnexo").toString());if(bd.setInserir(Inserir)){returntrue;}else{returnfalse;}}catch(Exceptione){System.out.println("setExcluir "+e);returnfalse;}}