java中字符串数据的压缩与解压

新手上路,请多包涵

我正在使用以下代码来压缩和解压缩字符串数据,但我面临的问题是,它很容易被无误地压缩,但解压缩方法会抛出以下错误。

线程“main”中的异常 java.io.IOException:不是 GZIP 格式

public static void main(String[] args) throws Exception {
    String string = "I am what I am hhhhhhhhhhhhhhhhhhhhhhhhhhhhh"
            + "bjggujhhhhhhhhh"
            + "rggggggggggggggggggggggggg"
            + "esfffffffffffffffffffffffffffffff"
            + "esffffffffffffffffffffffffffffffff"
            + "esfekfgy enter code here`etd`enter code here wdd"
            + "heljwidgutwdbwdq8d"
            + "skdfgysrdsdnjsvfyekbdsgcu"
            + "jbujsbjvugsduddbdj";

    System.out.println("after compress:");
    String compressed = compress(string);
    System.out.println(compressed);
    System.out.println("after decompress:");
    String decomp = decompress(compressed);
    System.out.println(decomp);
}

public static String compress(String str) throws Exception {
    if (str == null || str.length() == 0) {
        return str;
    }
    System.out.println("String length : " + str.length());
    ByteArrayOutputStream obj=new ByteArrayOutputStream();
    GZIPOutputStream gzip = new GZIPOutputStream(obj);
    gzip.write(str.getBytes("UTF-8"));
    gzip.close();
    String outStr = obj.toString("UTF-8");
    System.out.println("Output String length : " + outStr.length());
    return outStr;
}

public static String decompress(String str) throws Exception {
    if (str == null || str.length() == 0) {
        return str;
    }
    System.out.println("Input String length : " + str.length());
    GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(str.getBytes("UTF-8")));
    BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
    String outStr = "";
    String line;
    while ((line=bf.readLine())!=null) {
        outStr += line;
    }
    System.out.println("Output String lenght : " + outStr.length());
    return outStr;
}

仍然无法弄清楚如何解决这个问题!

原文由 rampuriyaaa 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

这是因为

String outStr = obj.toString("UTF-8");

Send the byte[] which you can get from your ByteArrayOutputStream and use it as such in your ByteArrayInputStream to construct your GZIPInputStream .以下是需要在您的代码中完成的更改。

 byte[] compressed = compress(string); //In the main method

public static byte[] compress(String str) throws Exception {
    ...
    ...
    return obj.toByteArray();
}

public static String decompress(byte[] bytes) throws Exception {
    ...
    GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes));
    ...
}

原文由 Rahul 发布,翻译遵循 CC BY-SA 3.0 许可协议

上面的答案解决了我们的问题,但除此之外。如果我们试图解压缩未压缩的(“不是 zip 格式”) byte[] 。我们将收到“不是 GZIP 格式”的异常消息。

为了解决这个问题,我们可以在我们的类中添加附加代码。

 public static boolean isCompressed(final byte[] compressed) {
    return (compressed[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (compressed[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8));
}

我的带有压缩/解压缩功能的完整压缩类如下所示:

 import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GZIPCompression {
  public static byte[] compress(final String str) throws IOException {
    if ((str == null) || (str.length() == 0)) {
      return null;
    }
    ByteArrayOutputStream obj = new ByteArrayOutputStream();
    GZIPOutputStream gzip = new GZIPOutputStream(obj);
    gzip.write(str.getBytes("UTF-8"));
    gzip.flush();
    gzip.close();
    return obj.toByteArray();
  }

  public static String decompress(final byte[] compressed) throws IOException {
    final StringBuilder outStr = new StringBuilder();
    if ((compressed == null) || (compressed.length == 0)) {
      return "";
    }
    if (isCompressed(compressed)) {
      final GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(compressed));
      final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gis, "UTF-8"));

      String line;
      while ((line = bufferedReader.readLine()) != null) {
        outStr.append(line);
      }
    } else {
      outStr.append(compressed);
    }
    return outStr.toString();
  }

  public static boolean isCompressed(final byte[] compressed) {
    return (compressed[0] == (byte) (GZIPInputStream.GZIP_MAGIC)) && (compressed[1] == (byte) (GZIPInputStream.GZIP_MAGIC >> 8));
  }
}

原文由 Arun Pratap Singh 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题