Я знаю, я знаю, кто захочет сжать или распаковать большие файлы в java. Совершенно необоснованно. На данный момент приостановить недоверие и предположим, что у меня есть веская причина для разжатия большого файла ZIP.Случайный доступ к сжатому файлу без использования ZipFile (поскольку ZipFile имеет основную ошибку)
выпуск 1: ZipFile имеет bug (bug # 6280693), солнце исправлено это в java 1.6 (Mustang). Исправление не является полезным, поскольку наше программное обеспечение должно поддерживать java 1.4. Ошибка, как я понимаю, работает так. Когда выполняется следующий код, Java выделяет кусок памяти, достаточно большой для хранения всего файла.
ZipFile zipFile = new ZipFile("/tmp/myFile.zip");
Если /tmp/myFile.zip - 4gb, java выделяет 4gb. Это вызывает исключение из кучи. К сожалению, размер кучи + 4 ГБ не является приемлемым решением. = (
Решение выпустить 1:. Используйте ZipInputStream, чтобы иметь дело с файлом в виде потока и, таким образом, уменьшить и контролировать объем памяти
byte[] buf = new byte[1024];
FileInputStream fs = new FileInputStream("/tmp/myFile.zip")
ZipInputStream zipIn = new ZipInputStream(fs);
ZipEntry ze = zipIn.getNextEntry();
while (ze != null){
while ((int cr = zipIn.read(buf, 0, 1024)) > -1)
System.out.write(buf, 0, len);
ze = zipIn.getNextEntry();
}
Выпуск 2: Я хотел бы получить доступ к ZipEntries случайно, что. ., я хотел бы только распаковывать один ZipEntry, без необходимости искать через весь поток в настоящее время я строй список из zipEntries, называется ZES:
ZipInputStream zin = new ZipInputStream("/tmp/myFile.zip");
ZipEntry ze = zin.getNextEntry();
List<ZipEntry> zes = new ArrayList<ZipEntry>();
while(ze!=null){
zes.add(ze);
ze = zin.getNextEntry();
}
Тогда, когда мне нужно распаковывать конкретный ZipEntry I итерации через все zi pEntries, пока не найду соответствующий zipEntry, который я затем распакую.
ZipEntry ze = in.getNextEntry();
while (! ze.getName().equals(queryZe.getName())){
ze = zin.getNextEntry();
}
int cr;
while ((cr = zin.read(buf)) > -1)
System.out.write(buf, 0, cr);
Quertion: ZipFile имеет возможность случайного доступа к ZipEntries.
new BufferedInputStream(zipFile.getInputStream(zipEntry));
Как я могу получить эту же способность без использования ZipFile?
Обратите внимание, что у ZipInputStream есть несколько довольно strangebehavior.
Особенно хорошая документация по Java и ZipFiles можно найти здесь:
http://commons.apache.org/compress/zip.html
Заметки о переключении замены солнца ZipFile с Apache Commons ZipFile как предложено в ответах:
- Солнца ZipFile.entries() всегда возвращает ZipEntries в том порядке, в котором они происходят в файле, тогда как apache commons ZipFile.getEntries() возвращает записи случайным образом заказ. Это вызвало интересную ошибку, потому что в некотором коде предполагалось, что записи будут «в порядке».
Ваш ответ сработал, спасибо! –