Проблема не в разархивировании, а в неэффективном способе записи разархивированных данных обратно на диск.Мои тесты показывают, что использование
InputStream is = zip.getInputStream(entry); // get the input stream
OutputStream os = new java.io.FileOutputStream(f);
byte[] buf = new byte[4096];
int r;
while ((r = is.read(buf)) != -1) {
os.write(buf, 0, r);
}
os.close();
is.close();
вместо этого сокращает время выполнения метода в 5 раз (с 5 до 1 секунды для почтового файла размером 6 МБ).
Вероятный виновник - вашиспользование bis.available()
.Помимо неправильности (available возвращает число байтов до тех пор, пока не будет заблокирован вызов read, а не до конца потока), это обходит буферизацию, предоставляемую BufferedInputStream, требуя собственного системного вызова для каждого байта, скопированного в выходной файл.
Обратите внимание, что перенос в BufferedStream не является необходимым, если вы используете методы массового чтения и записи, как я делал выше, и что код для закрытия ресурсов не является безопасным для исключений (если чтение или запись по какой-либо причине дает сбойни is
, ни os
не будут закрыты).Наконец, если у вас есть IOUtils в пути к классам, я рекомендую использовать их хорошо проверенные IOUtils.copy
вместо того, чтобы бросать свои собственные.