Эффективное извлечение файла из банки - PullRequest
1 голос
/ 20 июня 2009

У меня есть приложение, написанное на Java, которое использует файл JAR (он использует более одного, но это не главное).

Дело в том, что файл Jar, который я использую, содержит файлы, которые я абсолютно ДОЛЖЕН извлечь в файловую систему.

Пока что я использую Class.getResourceAsStream и FileOutputStream, но этот метод несколько медленный. Обратите внимание, что некоторые из этих файлов основаны на тексте, а другие - просто двоичные.

Таким образом, кроме попыток уменьшить необходимость извлечения файлов из JAR-файлов, есть ли какие-либо оптимизации (например, более адекватные функции) для этих задач.

Обратите внимание, что мое приложение основано на Java 6, и я хотел бы уменьшить внешние зависимости до минимума.

РЕДАКТИРОВАТЬ: Для дальнейшего использования мой СТАРЫЙ (неэффективный) код был:

int c;
while((c = is.read())!=-1){
    fos.write(c);
}

Новый, гораздо более быстрый код см. В принятом ответе.

Ответы [ 3 ]

7 голосов
/ 20 июня 2009

У вас есть контроль над файлом jar? Если вы создаете его без сжатия, то может сделать его быстрее. Очевидно, это увеличит размер файла jar ...

Еще одна вещь, чтобы проверить - как вы распаковываете файл? Например, если вы делаете это побайтово, это будет мучительно медленно. Используйте что-то вроде этого:

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

Если вы уже делаете это, не могли бы вы дать нам больше информации? Насколько медленно "несколько медленно"? Как это сравнить, скажем, с использованием утилиты jar для извлечения файла jar?

1 голос
/ 20 июня 2009

Err. Я не уверен, что вы действительно хотите сделать - но вы думали об использовании winzip?

Очевидно, что если вам нужно динамически извлекать файлы во время выполнения, это не сработает - но я не уверен, зачем вам это нужно - как часто меняется этот jar-файл ?.

Конечно, вы можете извлечь их один раз, а затем распространить их с приложением?

0 голосов
/ 20 июня 2009

Я согласен с Джоном. 2 вещи сделают добычу быстрее:

  1. Снижение уровня сжатия.
  2. Увеличение размера буфера, используемого при копировании / извлечении.

Полагаю, необходимость распаковки связана с требованием записи / перечитывания из файла Если файлы достаточно малы, память достаточно велика, и постоянный характер файлов не является обязательным; Вы можете рассмотреть отображение всего ресурса в память вместо использования диска в качестве хранилища.

...