Java 在不使用ZipFile的情况下随机访问压缩文件(因为ZipFile有一个主要bug)

Java 在不使用ZipFile的情况下随机访问压缩文件(因为ZipFile有一个主要bug),java,compression,zipfile,zipinputstream,Java,Compression,Zipfile,Zipinputstream,我知道,我知道,谁会想用java压缩或解压大文件。完全不合理。暂不怀疑,并假设我有一个很好的理由解压缩一个大的zip文件 问题1:有一个,sun在Java1.6(Mustang)中修复了这个问题。修复程序没有帮助,因为我们的软件需要支持Java1.4。据我所知,这个bug是这样工作的。当运行以下代码时,Java会分配足够大的内存块来保存整个文件 ZipFile zipFile = new ZipFile("/tmp/myFile.zip"); 如果/tmp/myFile.zip是4gb,jav

我知道,我知道,谁会想用java压缩或解压大文件。完全不合理。暂不怀疑,并假设我有一个很好的理由解压缩一个大的zip文件

问题1:有一个,sun在Java1.6(Mustang)中修复了这个问题。修复程序没有帮助,因为我们的软件需要支持Java1.4。据我所知,这个bug是这样工作的。当运行以下代码时,Java会分配足够大的内存块来保存整个文件

ZipFile zipFile = new ZipFile("/tmp/myFile.zip");
如果/tmp/myFile.zip是4gb,java将分配4gb。这会导致堆外异常。不幸的是,+4gb的堆大小不是一个可接受的解决方案=(

问题1的解决方案:使用,将文件作为流处理,从而减少和控制内存占用

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:我想随机访问Zippentries。也就是说,我只想解压缩一个Zippentries,而不必搜索整个流。目前我正在建立一个Zippentries列表,称为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();
        }
查询:ZipFile可以随机访问ZipPentries

new BufferedInputStream(zipFile.getInputStream(zipEntry));
不使用ZipFile,我如何获得同样的能力

请注意,ZipInputStream有一些非常重要的特性

关于java和ZipFile的特别好的文档可以在这里找到:

关于将sun ZipFile替换为apache commons ZipFile的说明,如回答中所述:

  • Sun总是按照ZipEntries在文件中出现的顺序返回ZipEntries,而apache commons则以随机顺序返回条目。这导致了一个有趣的错误,因为一些代码假设条目是“有序的”

  • 您可以查看,它与1.4+兼容,但我不知道它是否在引擎盖下暴露了相同的错误。

    对于此任务,您可能需要查看,或者。所有这些都应该与Java 1.4兼容,并且可能支持您需要的功能。

    它不兼容?那么这是什么?哦,我的错了!谢谢!=)23MB仅用于存档支持?真的?我的整个应用程序有15个以上的活动,重量为4MB。我认为用户使用如此繁重的应用程序来完成琐碎的任务是对他们的不尊重。
    new BufferedInputStream(zipFile.getInputStream(zipEntry));