quarta-feira, 7 de julho de 2010

Zips exóticos em Java

A API do Java é enorme, mas ainda deixa alguns pontos importantes abertos. Apesar de ter facilidades para ler e escrever arquivos compactados, não suporta zips encriptados ou multi-volumes.

Por sorte, existe uma API para Java sobre o 7-zip. É preciso usar a API e as bibliotecas originais, então existe uma biblioteca para o Linux e outra para o Windows. Pode ser um pouco trabalhoso para quem desenvolve no Windows e usa o Linux para produção, como muitas vezes acontece.

Pois bem, a API é deveras estranha, então o melhor é conseguir um exemplo e reaproveitá-lo.

RandomAccessFile file=new RandomAccessFile(zip, "r");
ISevenZipInArchive zip=SevenZip.openInArchive(null,
new RandomAccessFileInStream(file));
ISimpleInArchive ui=zip.getSimpleInterface();
for(int i=0; i<zip.getNumberOfItems(); i++) {
final ByteArrayOutputStream stream=new ByteArrayOutputStream();
String nome=(String) zip.getProperty(i, PropID.PATH);
ISimpleInArchiveItem item=ui.getArchiveItem(i);
ExtractOperationResult result=item.extractSlow(new ISequentialOutStream() {
public int write(byte[] data) throws SevenZipException {
try {
stream.write(data);
} catch(Exception e) {

}
return data.length;
}
}, "senhasecreta");

O arquivo sendo analisado é o zip (uma referência do tipo File). Para cada arquivo dentro de zip, obtem-se um item (do tipo ISimpleInArchiveItem) e descompactam-se os dados originais usando o método extractSlow(). Esse método recebe uma instância de ISequentialOutStream que neste caso copia os dados para uma instância de ByteArrayOutputStream. O último parâmetro de extractSlow() é a senha, caso os dados estejam protegidos.

É muito útil, mas espero que a JDK logo ganhe novos métodos para suportar encriptação e multi-volumes. E com uma API mais elegante que esta!

Nenhum comentário: