Problema com File.delete()

21 respostas
W

Pessoal, pelo que eu vi por ai, pra deletar um arquivo, basta fazer algo do tipo :

File file = new File("D:\TestaProcess\ped0001.ped"); file.delete();
porém, o após executado, vejo que o arquivo não foi deletado…

21 Respostas

M

Veja se o diretório é protegido contra gravações. O método delete da classe File pode lança uma SecurityException, por tanto, trate essa exceção. Outra coisa, o método retorna um booloeano para indicar se o arquivo foi ou não deletado.

W

Não tem exceções

M

Qual o retorno do método delete? Outra coisa, você deve tratar a exceção, pois ela pode ser lançada caso o arquivo que você queira apagar esteja em um diretório protegido contra gravação.

B

Opa beleza,

Apenas para te lembrar o metodo “delete()” retorna TRUE ou FALSE caso tenha conseguido ou não deletar o arquivo, verifique se no seu teste esta retornando TRUE;

Outra possibilidade é que seu “path” do seu arquivo pode estar errado, tem um tutorial aqui do GUJ que talvez te ajude
http://www.guj.com.br/articles/13

[]'s

J

Wilson,

O método delete retorna um boolean, que certamente está te devolvendo false. O problema da API do java.io é a falta de mensagens de erro. Na maioria dos casos o arquivo não é excluído por falta de permissão, veja se é esse seu caso.

Você pode verificar se o arquivo existe também.

Att.

W

Eu fiz o seguinte..

private BufferedReader br=null;
private FileInputStream flimp= null;

flimp = new FileInputStream(file);
br = new BufferedReader(new InputStreamReader(flimp, Charset.forName("ISO-8859-1")));

//No final do método, eu dei um .close em ambos, e logo em seguida dei um delete no arquivo

flimp.close();
br.close();
file.delete();
M

Você deve deletar o arquivos antes de chamar o método close do inputStream. O método close do inputStream chama o método close do arquivo internamente. Ou seja, você está tentando deletar um arquivo que já foi fechado.

private BufferedReader br=null;
private FileInputStream flimp= null;

flimp = new FileInputStream(file);
br = new BufferedReader(new InputStreamReader(flimp, Charset.forName("ISO-8859-1")));

//No final do método, eu dei um .close em ambos, e logo em seguida dei um delete no arquivo

file.delete();// Aqui que o arquivo deve ser deletado.
flimp.close();
br.close();
W

Dessa forma, o arquivo não é deletado… ;s

E

O Windows não deixa você apagar arquivos abertos, apenas arquivos fechados. O método “delete” retorna false porque não conseguiu remover o arquivo.

O Unix e o Linux deixam você apagar arquivos abertos; quando o arquivo for fechado, ele será automaticamente removido.

M

um outro detalhe também que eu ja tive problema, era que referenciava o arquivo direto por um File e tentava dar o delete nele e não ia… ai alguém me avisou aqui no guj de que as vezes você precisa chamar o garbage collector para apagar o motivo, sabe-se deus o por quê…

então eu fiz um negocio ± assim e passou a funcionar:

boolean apagado = false;
File arquivo = new File("<endereço>");

while(!apagado){
     apagado = arquivo.delete();
     System.gc();

}
M

Mas quando você chama o garbage collector não é garantido que ele seja de fato executado

E

O garbage collector deve fechar arquivos que por algum motivo continuaram abertos (porque o fulano se esqueceu de dar um close, preferencialmente dentro de uma cláusula “finally” para forçar a fechar o arquivo mesmo que tenha ocorrido alguma coisa.).
Mas como esse processo depende de um “finalizer”, o fechamento deve ocorrer apenas na segunda ou terceira “full garbage collection”. Isso é um comportamento não documentado; em application servers, pode-se até desabilitar o System.gc() para evitar que os programadores façam esse tipo de mágica (chamar System.gc para contornar erros de programação).

O correto é sempre fechar os arquivos direitinho.

M

entanglement:
O garbage collector deve fechar arquivos que por algum motivo continuaram abertos (porque o fulano se esqueceu de dar um close, preferencialmente dentro de uma cláusula “finally” para forçar a fechar o arquivo mesmo que tenha ocorrido alguma coisa.).
Mas como esse processo depende de um “finalizer”, o fechamento deve ocorrer apenas na segunda ou terceira “full garbage collection”. Isso é um comportamento não documentado; em application servers, pode-se até desabilitar o System.gc() para evitar que os programadores façam esse tipo de mágica (chamar System.gc para contornar erros de programação).

O correto é sempre fechar os arquivos direitinho.

Só complementando. Quando alguém chama System.gc(), essa chamada só está somente sugerindo ao garbage collector que essa é a hora de ele agir. Mesmo assim, a decisão final de quando e como será efetuada a coleta de lixo sempre será do próprio garbage collector. Falo isso porque nosso amigo maior_abandonado usou uma chamada ao gc para tentar fechar os arquivos abertos e de fato efetuar a deleção do arquivo. Não se pode contar com isso.

M

Como citato pelo entanglement, pode-se desabilitar a jvm para aceitar chamdas explícitas ao garbage collector. Isso é feito mediante à inclusão da seguinte linha no arquivo de parâmetros de inicialização da jvm:

-XX:+DisableExplicitGC
M

sim, eu sei que não é garantido, varia de jvm para jvm (ja ouvi falar que a da sun costuma chamar), mas essa é uma forma pela qual eu resolvi quando tive o mesmo problema… se o cara passa argumento de execução dizendo para ignorar chamadas ao gc e ele reclamar que a chamada ao gc não funcionou não se tem nem o que responder…

M

Mas ai é que tá, quem faz essa configuração obviamente não é o desenvolvedor, mas o pessoal da arquitetura que configura o ambiente sobre o qual a aplicação vai rodar. Eles fazem isso pra evitar que falhas de programação sejam encobertas por chamadas ao gc. Isso é muito usado em aplicações enterprise, em ambientes servidor, como o próprio entaglement citou.

E

Um system.gc em uma JVM, em determinadas condições, pode demorar uns 10 a 30 segundos, ou até minutos, que é um tempo inaceitável em um servidor de aplicações. Portanto, normalmente é desabilitado. Quem deve tomar a decisão de efetuar uma “full garbage collection” é a própria JVM, não um programador preguiçoso.

M

eu entendo que se um arquivo estiver aberto o delete não vai funcionar, mas o caso não era esse… como eu citei la atras o arquivo era referenciado direto em um File, eu não cheguei a abrir nenhum inputStream relativo a ele nem tão pouco abri ele por fora em algum outro software e o erro acontecia (o objeto file em questão vinha de retorno no listFiles se bem me lembro, do file do diretorio dele), e assim mesmo esse problema acontecia… e era arquivo antigo, de dias atrás a máquina provavelmente ja tinha sido reiniciada n vezes e então o arquivo seria apagado… não tem nada a ver com com “preguiça” ou código mau feito…

o so era o windows xp se não me engano…

M

Quando ele falou preguiçoso falou de forma genérica. Quando eu falei que a chamada do gc poderia ser desabilita para evitar que alguém use isso para esconder um código mal feito, também me referi de forma genérica . Ninguém aqui quis ofendê-lo, apenas estamo querendo alertar que não se pode confiar em uma chamada ao gc, pois o mesmo pode demorar tempo suficiente que chegue a ponto de afetar a aplicação, só isso.

M

Quando ele falou preguiçoso falou de forma genérica. Quando eu falei que a chamada do gc poderia ser desabilita para evitar que alguém use isso para esconder um código mal feito, também me referi de forma genérica . Ninguém aqui quis ofendê-lo, apenas estamo querendo alertar que não se pode confiar em uma chamada ao gc, pois o mesmo pode demorar tempo suficiente que chegue a ponto de afetar a aplicação, só isso.

sim, entendemos que tenha sido dito de forma generica, mas não acredito que seja exatamente o que vocês disseram (ao menos não em qualquer caso, pode ser que esse problema só aconteça em um SO especifico pro exemplo… sei la) por que eu tive esse mesmo problema e nem sequer abri algum inputStream, quanto mais esqueci de fechar como vocês disseram, de qualquer forma em certos casos o arquivo simplesmente precisa ser apagado, não tem referência nenhuma de alguém lendo-o como tinha dito e assim mesmo o problema ocorre (experiência própria). Então para apagarmos devemos pagar um preço, ou chamamos Runtime e acabamos com o lado multiplataforma, ou chamamos o gc antes e depois damos o delete ou simplesmente o arquivo não é apagado (a menos que você me diga outra forma de fazer isso…). O gc demorar tantos segundos para apagar um arquivo é mais raro do que ser importante apagar estes arquivos (de repente para não acumularem e ficarem ocupando muito espaço), cabe a quem está envolvido com o processo decidir o que fazer, cada caso é um caso…

quanto a eu ficar ofendido acho meio pouco para chegar a ficar ofendido, mas considero que a explicação se faz necessária numa situação dessas.

E

Só para não dizer que o System.gc é sempre mau, ou indicativo de preguiça na programação.

Muitas vezes, quando vou escrever um sistema Desktop que processa algo em várias fases distintas (como se fossem batches), ponho um System.gc entre uma fase e outra, até porque

a) Eu não tenho, nesse caso, uma restrição de tempo de espera para uma requisição simples,

e

b) Eu sei que, nesse sistema em particular, um monte de coisas que foram criadas em uma fase não precisam sobreviver para a próxima fase, então eu dou uma “ajudinha” aos algoritmos e indico explicitamente que quero um System.gc nessa mudança de fase, para deixar a memória bem limpa e organizada.

Criado 13 de julho de 2011
Ultima resposta 13 de jul. de 2011
Respostas 21
Participantes 6