Problema com File.delete()

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…

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.

Não tem exceções

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.

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

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.

Eu fiz o seguinte…

[code]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();

[/code]

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.

[code]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();
[/code]

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

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.

1 curtida

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();

}
2 curtidas

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

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.

1 curtida

[quote=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.
[/quote]

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.

1 curtida

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

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…

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.

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.

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…

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.