Como forçar o fechamento de um arquivo

[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;
		}
	}