[Resolvido] - Extrair Arquivos RAR

Ola, Sres…

Realmente espero q esse topico nao esteja repetido, pq o tanto q ja procurei aki msm no forum e no ‘pai dos burros’ nao ta na conta, hehe.
O que acontece é que tenho uma rotina java que processa arquivos zip e txt, extraindo e lendo os txt inside e gravando no banco.
O zip to lendo e ta funfando blz.
Mas o rar… ta osso!

Nao encontrei nada…
Na verdade, ate achei esse topico aki: http://www.guj.com.br/posts/list/32689.java, mas preciso fazer essa extracao via codigo Java.
Essa biblioteca ‘parecia’ ser td o q eu preciso, mas apenas lista os arquivos: http://code.google.com/p/raroscope/
E esse exemplo aki nao funfou, tbem…http://www.example-code.com/java/rar_unrar.asp
Essa biblioteca suporta apenas ate rar versão 2, sendo q o winrar atual ja esta na 3.9x…http://hem.bredband.net/catacombae/jlrarx.html#rarlib

Se conseguir pegar o ‘InputStream’ dos arquivos que vem dentro do rar ja estara de bom tamanho, pois a partir dai posso manipula-los com o FileOutputStream, etc…
Mas pelo que parece, o algoritmo pra descompactar o rar é proprietario…

No entanto, conto com vcs, galera…

Abs!

Fala ae,

Vc estudou a fundo a http://code.google.com/p/raroscope/? pq ela diz que faz a descompressão…

Gde BrunoCarlo… vlw pela resposta!

Mas na verdade, nao eh nao…

Esse trecho q vc colocou aki fala apenas do tamanho do arquivo compactado/descompactado.
Veja a ultima frase desse quote aki abaixo:

[quote]What RARoScope can’t do?

However, because of various factors, RARoScope does have its limitations and can’t do the following.

Creating RAR archives.
Because of the proprietary nature of the RAR archive format, RARoScope can’t be used to create RAR archives.

Reading file contents/decompressing.
Since RARoScope has been poised as more of a “RAR scanning library” rather than a “RAR decompressor” for Java, it can’t do the decompressing part. However, this is open to change in the near future. Depending on the response I get, I might implement a decompressing logic.[/quote]

Para entender um pouco melhor sobre a falta de bibliotecas para RAR veja: http://en.wikipedia.org/wiki/RAR#Software

A maioria dos programas gratuitos só suportam até a versão 2 do RAR (uma vez que o autor não autorizou que esses programas fossem atualizados para suportar a versão 3).

Para uma possível solução (escrita em C++, talvez tenha que ser portada para Java ou algo parecido) veja: http://en.wikipedia.org/wiki/Unrar#See_also (a RAR Lab disponibiliza o fonte do descompressor RAR, mas é preciso analisar as questões de licença)

Galera…

desde já agradeco as respostas do BrunoCarlo e do marcobiscaro2112

Até agora consegui uma solução parcial.
Pelo que conversei com alguns profissionais, amigos e até mesmo encontrei garimpando na Internet é que a melhor forma de se fazer isso é chamando um programa externo.

Assim sendo, tanto em Mac qto em Linux está funcionando beleza… mas no velho e ‘tenso’ Windows ainda está com um probleminha…
Vejam como ficou o codigo:

								String osName = System.getProperty("os.name");
								String extrair = StringUtils.EMPTY;
								if(osName.contains("Mac")){
									extrair = "unrar x " + fileProcessamento + " " + pathExtracaoArquivo;
								}else if(osName.contains("Linux")){
									extrair = "unrar -x " + fileProcessamento + " " + pathExtracaoArquivo;
								}else if(osName.contains("Windows")){
									extrair = "WINRAR -x " + fileProcessamento + " " + pathExtracaoArquivo;
									
								}
								if(StringUtils.isNotEmpty(extrair)){
									Runtime.getRuntime().exec(extrair);
									fileProcessamento.delete();
								}

O problema que acontece no Windows é que ele reclama de o arquivo já estar sendo usado por outro processo, o que não aconteceu nem no Mac nem no Linux (Ubuntu).
Vejam, dei um print da tela com o erro:

Mais uma vez, conto com os colegas… vlw, galera!

Algumas sugestões:

Não é preciso fazer duas verificações se o comando é o mesmo no Mac e no Linux o comando é o mesmo:

if(osName.contains("Mac") || osName.contains("Linux")){
									extrair = "unrar x " + fileProcessamento + " " + pathExtracaoArquivo;
								} else if(osName.contains("Windows")){
									extrair = "WINRAR -x " + fileProcessamento + " " + pathExtracaoArquivo;
									
								}

Outra coisa: não esqueça de colocar o Runtime.exec dentro de um bloco try…catch. É preciso tratar a possível exceção caso o programa de descompressão não esteja instalado.

Por fim, quanto ao seu problema com o Windows, certifique-se que seu programa não esteja modificando nem acessando o arquivo ao mesmo tempo (e caso ele tenha sido acessado antes, não esqueça de fechar qualquer Input ou OutputStream usado).

Gde marcobiscaro2112, vlw msm pelas dicas… cara!

Na verdade já tem o try/catch… é q só colei o trecho de codigo com problema.

De Linux pra Mac tem uma sutil diferenca, que é o sinal de ‘-’ q só é necessário no Linux… no Mac não precisa (se colocar dá erro).
E vou conferir o FileOutputStrem… tomara q seja isso, hehe

Vlw por td ai!

Assim q eu conferir se é isso mesmo, volto aqui e coloco o topico como resolvido.

Abs!

Bem, na verdade você pode usar sem o sinal de menos nos dois sistemas. Mas isso é um detalhe totalmente irrelevante. Tomara que você encontre o problema.

Gde marcobiscaro2112, era apenas isso q faltava… cara!

Fechar o FileOutPutStream:

								FileOutputStream fos = new FileOutputStream(pathDir + dirArquivo + File.separator + pathRar);
								fos.write(arquivoRemessa.getArquivo().getImagem());
								fos.close();

Td funcionando beleza aki, agora…

vlw, msm!