Java IO - Não está removendo o diretório

18 respostas
A

Olá galera, como vai?
Estou com a seguinte dificuldade:

A partir do método main inicio um fluxo de execução, ao qual são chamados diversos métodos, a questão é que o último método
é o de deleção, o que deveria limpar os arquivos e/ou diretórios gerados temporariamente no c:/ do computador. Mas ele não faz, ele remove
parcialmente, e sempre sobram os mesmos arquivos de uma pastinha que foi passada como sendo um File… Sei lá é como estivessem abertos
impossibilitando ser removidos pois, se eu executo, colocando um debug no método de deleção e ao cair nele dar um stop e posteriormente
executá-lo separadamente ele irá limpar certinho… Vejam abaixo o meu método de deleção…

/** * Método que recebe um File podendo ser arquivo ou diretório. * @param File dir * */ public static boolean deleteDir(File dir) { if (dir.isDirectory()) { String[] children = dir.list(); for (int i=0; i<children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } } return dir.delete(); }

Alguém tem alguma sugestão?

18 Respostas

A

Vejam como eu acho o método:

/** * Remove todos os registros temporários gerados no diretório c:/. */ final File[] registrosTemporariosAseremRemovidos = { oebps, metaInf, mimeType, epubFullZipado }; for (int i = 0; i < registrosTemporariosAseremRemovidos.length; i++) { DelecaoArquivoDiretorio.deleteDir(registrosTemporariosAseremRemovidos[i]); }

A

Acredito que não tenho problema no método de delação… Mas o que pode ser?

A

Descobrí uma coisa, olha só a mensagem que meu Windows 7 está mostrando:

“The action can’t be completed because the folder or file in its open in another program”

Agora é implementar a solução e já era… Vou pesquisando mais…

Abraço,

A

Descobrí também que são exatamente 7 arquivos os quais o Java não consegue deletar. Alguém conhece alguma maneira de forçar deleção?

A

Testei usando o método de File deleteOnExit() também falhou…

Caroline_Alow

nossa i naum funcionou com o metodo delete?

A

Oi Carol, obrigado por ajudar.
Não, não funcionou o método delete()

A

Tentei deixar todos File assim que termina o processo, receberem file = null, mas também sem sucesso.

A

Além de fechar os FileInputStreams com close()

A

Encontrei a solução, mas acredito que não seja uma forma muito aplicável...
Estou chamando:

/**
		 * Chamada para limpeza de memória.
		 */
		System.gc();

Um passo antes de invocar o método de deleção na pilha de execução...

Alguém teria alguma sugestão?

davidbuzatto

Os diretórios que você está tentando excluir estão vazios?
Você leu a documentação do método delete?

A

Oi davidbuzatto, obrigado pela dica... :D

Vou explicar melhor, acredito que escreví rapidamente acima vou usar palavras mais claras:

- O Windows 7 e o XP falam que alguns arquivos desta pasta que não exclui nem a pau está em uso por algum programa... Esse tal algum programa
acredito que seja a Virtual Machine, isto é, ao invocar o método de start da pilha de execução... O último método invocado é o de deleção, veja o código:

public static void deleteDir(File dir) {  
        if (dir.isDirectory()) {  
            String[] children = dir.list();  
            for (int i=0; i<children.length; i++) {  
                    
               File file = new File(dir.getAbsolutePath()+"\"+children[i]);
               deleteDir(file);
            }  
        } else{
                dir.delete();
        }
        dir.delete();  
    }

Se observar o código verá que ele usa recursividade para limpar a pasta antes de tentar excluí-la...

Fui claro?

Abraços,
André AS

drigo.angelo

O código que chama esse método seu cria um File, certo?
Creio que se você passasse apenas uma String com o camniho, e dentro do método criasse o file seria melhor, pois fica um resquício do arquivo que você está querendo deletar no método que chama o deleteDir(…);

davidbuzatto

Além dos diretórios estarem vazios, é claro, vc não pode ter nenhum arquivo aberto no momento (nenhum stream amarrado ao arquivo).
Então vc tem que fechar todos os streams para os arquivos como vc disse que já fechou.

O método recursivo para excluir diretórios pode ser simplificado.

public static void deleteDir( File dir ) {
    
    // itera por todos os arquivos do diretório
    for ( File f : dir.listFiles() ) {

        // o arquivo atual é um diretório?
        if ( f.isDirectory() ) {
            // invoca deleteDir para apagar os arquivos de dentro
            // deste diretório
            deleteDir( f );
        } else {
            // apaga o arquivo
            f.delete();
        }

    }

    // apaga o diretório
    dir.delete();

}

Para tornar o método mais genérico, vc pode ainda verificar se o file passado ao método é realmente um diretório antes de entrar no for e ainda retornar true ou false caso a operação tenha sido bem sucedida. Pode até modificar o método para excluir qualquer tipo de arquivo. Ficaria algo assim:

public static void delete( File file ) {

    // não é null
    if ( file != null ) {
        
        // e é um diretório
        if ( file.isDirectory() ) {
            
            // itera por todos os arquivos do diretório
            for ( File f : file.listFiles() ) {

                // o arquivo atual é um diretório?
                if ( f.isDirectory() ) {
                    // invoca delete para apagar os arquivos de dentro
                    // deste diretório
                    delete( f );
                } else {
                    // apaga o arquivo
                    f.delete();
                }

            }
        
        }
        
        // apaga o arquivo (pode ser um diretório ou não)
        file.delete();

    }

}

[]'s

A
drigo.angelo:
O código que chama esse método seu cria um File, certo? Creio que se você passasse apenas uma String com o camniho, e dentro do método criasse o file seria melhor, pois fica um resquício do arquivo que você está querendo deletar no método que chama o deleteDir(...);

Em primeiro lugar, obrigado por ajudar...

Veja como estou passando:

public static void removeRegistrosTemporarios(){
		final File[] registrosTemporariosAseremRemovidos = {
		    	PASTA1, // Deleta todo seu conteúdo e depois ela
		    	ARQUIVO1, // Deleta o arquivo certinho...
		    	PASTA2, // Essa é a que não deleta...
			PASTA_ZIPADA	// Deleta certinho também		    
		};
		
		for (int i = 0; i < registrosTemporariosAseremRemovidos.length; i++) {
				DelecaoArquivoDiretorio.deleteDir(registrosTemporariosAseremRemovidos[i]);
		}
	}

Você fala para ao invés de eu passar File passar String? Vou fazer esse teste...

A
davidbuzatto:
Além dos diretórios estarem vazios, é claro, vc não pode ter nenhum arquivo aberto no momento (nenhum stream amarrado ao arquivo). Então vc tem que fechar todos os streams para os arquivos como vc disse que já fechou.

O método recursivo para excluir diretórios pode ser simplificado.

public static void deleteDir( File dir ) {
    
    // itera por todos os arquivos do diretório
    for ( File f : dir.listFiles() ) {

        // o arquivo atual é um diretório?
        if ( f.isDirectory() ) {
            // invoca deleteDir para apagar os arquivos de dentro
            // deste diretório
            deleteDir( f );
        } else {
            // apaga o arquivo
            f.delete();
        }

    }

    // apaga o diretório
    dir.delete();

}

Para tornar o método mais genérico, vc pode ainda verificar se o file passado ao método é realmente um diretório antes de entrar no for e ainda retornar true ou false caso a operação tenha sido bem sucedida. Pode até modificar o método para excluir qualquer tipo de arquivo. Ficaria algo assim:

public static void delete( File file ) {

    // não é null
    if ( file != null ) {
        
        // e é um diretório
        if ( file.isDirectory() ) {
            
            // itera por todos os arquivos do diretório
            for ( File f : file.listFiles() ) {

                // o arquivo atual é um diretório?
                if ( f.isDirectory() ) {
                    // invoca delete para apagar os arquivos de dentro
                    // deste diretório
                    delete( f );
                } else {
                    // apaga o arquivo
                    f.delete();
                }

            }
        
        }
        
        // apaga o arquivo (pode ser um diretório ou não)
        file.delete();

    }

}

[]'s

davidbuzatto, gostei das dicas vou tentar implementá-las também...

A

O teste de mudar String por File não funcionou… Pois dá n erros durante o processo de compactar… Do método genérico… Vou testar de novo com mais calma…

Mais sugestões?

Caroline_Alow

drigo.angelo:
O código que chama esse método seu cria um File, certo?
Creio que se você passasse apenas uma String com o camniho, e dentro do método criasse o file seria melhor, pois fica um resquício do arquivo que você está querendo deletar no método que chama o deleteDir(…);

num entendí com faiz mudar di file pra string pq teria diferença…???

Criado 24 de janeiro de 2011
Ultima resposta 26 de jan. de 2011
Respostas 18
Participantes 4