这是 Java GZipInputStream 类中的错误吗?

2024-03-13

我注意到我的一些 gzip 解码代码似乎无法检测到损坏的数据。我认为我已将问题追溯到 Java GZipInputStream 类。特别是,当您使用单个“read”调用读取整个流时,损坏的数据似乎不会触发 IOException。如果您在两次或多次调用中读取相同损坏数据的流,那么它确实会触发异常。

在考虑提交错误报告之前,我想了解这里的社区的想法。

编辑:我修改了我的示例,因为最后一个示例没有清楚地说明我认为的问题。在这个新示例中,对 10 字节缓冲区进行 gzip 压缩,修改 gzip 缓冲区的一个字节,然后将其解压缩。对“GZipInputStream.read”的调用返回 10 作为读取的字节数,这就是您对 10 字节缓冲区的期望。然而,解压缩的缓冲区与原始缓冲区不同(由于损坏)。没有抛出异常。我确实注意到,在读取后调用“available”会返回“1”,而不是到达 EOF 时返回的“0”。

这是来源:

  @Test public void gzip() {
    try {
      int length = 10;
      byte[] bytes = new byte[]{12, 19, 111, 14, -76, 34, 60, -43, -91, 101};
      System.out.println(Arrays.toString(bytes));

      //Gzip the byte array
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      GZIPOutputStream gos = new GZIPOutputStream(baos);
      gos.write(bytes);
      gos.finish();
      byte[] zipped = baos.toByteArray();

      //Alter one byte of the gzipped array.  
      //This should be detected by gzip crc-32 checksum
      zipped[15] = (byte)(0);

      //Unzip the modified array
      ByteArrayInputStream bais = new ByteArrayInputStream(zipped);
      GZIPInputStream gis = new GZIPInputStream(bais);
      byte[] unzipped = new byte[length];
      int numRead = gis.read(unzipped);
      System.out.println("NumRead: " + numRead);
      System.out.println("Available: " + gis.available());

      //The unzipped array is now [12, 19, 111, 14, -80, 0, 0, 0, 10, -118].
      //No IOException was thrown.
      System.out.println(Arrays.toString(unzipped));

      //Assert that the input and unzipped arrays are equal (they aren't)
      org.junit.Assert.assertArrayEquals(unzipped, bytes);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

决定运行测试:

你错过了什么。gis.read(unzipped)返回 1,因此它只读取了一个字节。你不能抱怨,这不是流的结束。

下一个read() throws “损坏的 GZIP 预告片”.

所以一切都好! (并且至少在 GZIPInputStream 中没有错误)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这是 Java GZipInputStream 类中的错误吗? 的相关文章

随机推荐