extração eficiente do arquivo a partir de jar
Pergunta
Eu tenho um aplicativo escrito em Java que usa um arquivo jar (ele usa mais de um, mas isso não é o ponto).
O fato é que o arquivo JAR que estou usando contém arquivos que eu absolutamente deve extrair para o sistema de arquivos.
Até agora eu estou usando Class.getResourceAsStream e FileOutputStream, mas este método é um pouco lento. Note-se que alguns desses arquivos são baseados em texto, mas outros são simplesmente binário.
Assim, para além de tentar reduzir a necessidade de extrair arquivos de JARs, existem otimizações (como funções mais impeditivos) para estas tarefas.
Note que o meu pedido é Java 6-base e eu gostaria de reduzir dependências externas ao mínimo.
EDIT: Para referência futura, o meu código OLD (inefficent) foi:
int c;
while((c = is.read())!=-1){
fos.write(c);
}
Para o novo, muito mais rápido do código, ver a resposta aceita.
Solução
Você tem controle sobre o arquivo jar? Se você criá-lo descompactado, que pode torná-lo mais rápido. Obviamente ele vai fazer o arquivo jar maior embora ...
Outra coisa a verificar - como é que você extrair o arquivo? Por exemplo, se você está fazendo isso byte por byte será dolorosamente lento. Use algo como isto:
public static void copyStream(InputStream input, OutputStream output)
throws IOException
{
// Reads up to 8K at a time. Try varying this.
byte[] buffer = new byte[8192];
int read;
while ((read = input.read(buffer)) != -1)
{
output.write(buffer, 0, read);
}
}
Se você já está fazendo isso, você poderia nos dar mais informações? Como lento é "um pouco lento"? Como ele se compara com, digamos, usando o utilitário jar para extrair o arquivo jar?
Outras dicas
Err. Eu não tenho certeza do que você realmente quer fazer - mas você já pensou em usar o WinZip
Obviamente, se você precisa extrair os arquivos dinamicamente em tempo de execução Isso não vai funcionar - mas eu não sei por que você precisa fazer isso - como muitas vezes faz essa mudança arquivo jar ?.
Certamente você pode extraí-los uma vez e, em seguida, distribuí-los com a aplicação?
Concordo com Jon. 2 coisas vão fazer a extração mais rápida:
- Diminuir o nível de compressão.
- Aumentar o buffer porte usado quando copiar / extrair.
Eu estou supondo que a necessidade de extrair é devido a uma exigência de gravação / re-lido do arquivo. Se os arquivos são pequenos o suficiente, a memória é grande o suficiente e a natureza persistente de arquivos não é um requisito; você pode considerar o mapeamento de todo o recurso à memória em vez de usar o disco como armazenamento.