Java的ZipInputStream提取错误(Java ZipInputStream extrac

2019-09-26 19:05发布

下面是一些代码,由仅含有一个单一的文件zip文件中提取的文件。 但是,提取的文件不匹配,通过WinZip或其他压缩软件中提取相同的文件。 我希望,它可能由一个字节如果文件中包含的字节数为奇数(因为我的缓冲区大小2,我只是中止一次读取失败)关闭。 然而,在分析时(使用的WinMerge或DIFF)与下面通过的Winzip提取与代码文件中提取的文件,存在其中字节从Java提取缺少几个区域。 有谁知道为什么或如何解决这个问题?

package zipinputtest;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipInputStream;

public class test2 {
    public static void main(String[] args) {
        try {
            ZipInputStream zis = new ZipInputStream(new FileInputStream("C:\\temp\\sample3.zip"));
            File outputfile = new File("C:\\temp\\sample3.bin");
            OutputStream os = new BufferedOutputStream(new FileOutputStream(outputfile));
            byte[] buffer2 = new byte[2];
            zis.getNextEntry();
            while(true) {
                if(zis.read(buffer2) != -1) {
                    os.write(buffer2);
                }
                else break;
            }
            os.flush();
            os.close();
            zis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我是能够生产使用这种图像(保存并压缩为sample3.zip并在其上运行的代码)的错误,但足够大小的任何二进制文件应该表现出差异。

Answer 1:

while (true) {
    if(zis.read(buffer2) != -1) {
        os.write(buffer2);
    }
    else break;
}

通常的问题。 你忽略的计数。 应该:

int count;
while ((count = zis.read(buffer2)) != -1)
{
    os.write(buffer2, 0, count);
}

注意:

  1. 将2缓冲区大小为荒谬的。 使用8192以上。
  2. flush()之前close()是多余的。


Answer 2:

您可以使用更逐字的方法来检查所有的字节是否为读取和写入,例如像的方法

  public int extract(ZipInputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[BUFFER_SIZE];
    int total = 0;
    int read;
    while ((read = in.read(buffer)) != -1) {
      total += read;
      out.write(buffer, 0, read);
    }
    return total;
  }

如果read参数中没有使用write()该方法假定的全部内容buffer将被写入的,这可能是不正确的,如果buffer没有被完全填充。

所述OutputStream可冲洗并关闭内侧或外侧extract()方法。 调用close()应该是足够的,因为它也叫flush()

在任何情况下,“标准” I / O的Java代码,如java.util.zip包,已经过测试和广泛使用,所以这是极不可能它可能有作为如此重要的一个错误导致字节错过这么容易。



文章来源: Java ZipInputStream extraction errors