GZIPInputStream解压缩对于长度超过532字节的压缩数据不起作用

时间:2009-05-09 07:56:15

标签: java compression

我在java中使用gZipInputStream创建了压缩和解压缩 它适用于少量数据,但如果压缩后的数据长度大于532,则我的解压缩效果不佳。

由于 BAPI

3 个答案:

答案 0 :(得分:5)

重申其他人所说的话:

  • 通常情况是 str.length()!= str.getBytes()。length()。许多操作系统使用可变长度编码(如UTF-8, UTF-16 or Windows-949)。
  • 使用OutputStream.close方法确保正确写入所有数据。
  • 使用InputStream.read的返回值来查看已读取的字节数。无法保证一次性读取所有数据。
  • Be careful使用String类进行编码/解码时。

字符串压缩/解压缩方法

  private static byte[] compress(String str, Charset charset) {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    try {
      OutputStream deflater = new GZIPOutputStream(buffer);
      deflater.write(str.getBytes(charset));
      deflater.close();
    } catch (IOException e) {
      throw new IllegalStateException(e);
    }
    return buffer.toByteArray();
  }

  private static String decompress(byte[] data,
      Charset charset) {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    ByteArrayInputStream in = new ByteArrayInputStream(data);
    try {
      InputStream inflater = new GZIPInputStream(in);
      byte[] bbuf = new byte[256];
      while (true) {
        int r = inflater.read(bbuf);
        if (r < 0) {
          break;
        }
        buffer.write(bbuf, 0, r);
      }
    } catch (IOException e) {
      throw new IllegalStateException(e);
    }
    return new String(buffer.toByteArray(), charset);
  }

  public static void main(String[] args) throws IOException {
    StringBuilder sb = new StringBuilder();
    while (sb.length() < 10000) {
      sb.append("write the data here \u00A3");
    }
    String str = sb.toString();
    Charset utf8 = Charset.forName("UTF-8");
    byte[] compressed = compress(str, utf8);

    System.out.println("String len=" + str.length());
    System.out.println("Encoded len="
        + str.getBytes(utf8).length);
    System.out.println("Compressed len="
        + compressed.length);

    String decompressed = decompress(compressed, utf8);
    System.out.println(decompressed.equals(str));
  }

(请注意,因为这些是内存中的流,我不是being strict关于我如何打开或关闭它们。)

答案 1 :(得分:2)

对我来说看起来像char编码/解码问题。应该使用Readers/Writers来编写字符串,例如String.getBytes()。使用String(new byte[])构造 正确的方式..

你真的应该使用一个循环来读取并检查返回的字节读取值,以确保所有内容都被回读!

答案 2 :(得分:2)

我建议你使用gCompress.close()not finish();

我还建议您不要依赖str.length()足够长的时间来阅读。存在数据可能更长的风险,因此字符串将被截断。

您还忽略read()的返回值。 read()只保证read()一个字节,并且不太可能读取str.length()字节的数据,所以你可能有很多尾随的nul字节\ 0。相反,你可以期望读取str.getBytes()。length()