8

次の Java コードを使用して、文字列を圧縮および圧縮解除しようとしています。しかし、新しい ByteArrayInputStream オブジェクトから新しい GZipInputStream オブジェクトを作成する行は、「java.util.zip.ZipException: Not in GZIP format」例外をスローします。これを解決する方法を知っている人はいますか?

        String orig = ".............";

        // compress it
        ByteArrayOutputStream baostream = new ByteArrayOutputStream();
        OutputStream outStream = new GZIPOutputStream(baostream);
        outStream.write(orig.getBytes());
        outStream.close();
        String compressedStr = baostream.toString();

        // uncompress it
        InputStream inStream = new GZIPInputStream(new ByteArrayInputStream(compressedStr.getBytes()));
        ByteArrayOutputStream baoStream2 = new ByteArrayOutputStream();
        byte[] buffer = new byte[8192];
        int len;
        while((len = inStream.read(buffer))>0)
            baoStream2.write(buffer, 0, len);
        String uncompressedStr = baoStream2.toString();
4

3 に答える 3

10

ミキシングStringbyte[]; それは決して収まりません。また、同じエンコーディングの同じ OS でのみ動作します。すべてbyte[]を に変換できるわけではなくString、変換を戻すと他のバイトが返される可能性があります。

compressedBytes文字列を表す必要はありません。

getBytesとでエンコーディングを明示的に設定しnew Stringます。

    String orig = ".............";

    // Compress it
    ByteArrayOutputStream baostream = new ByteArrayOutputStream();
    OutputStream outStream = new GZIPOutputStream(baostream);
    outStream.write(orig.getBytes("UTF-8"));
    outStream.close();
    byte[] compressedBytes = baostream.toByteArray(); // toString not always possible

    // Uncompress it
    InputStream inStream = new GZIPInputStream(
            new ByteArrayInputStream(compressedBytes));
    ByteArrayOutputStream baoStream2 = new ByteArrayOutputStream();
    byte[] buffer = new byte[8192];
    int len;
    while ((len = inStream.read(buffer)) > 0) {
        baoStream2.write(buffer, 0, len);
    }
    String uncompressedStr = baoStream2.toString("UTF-8");

    System.out.println("orig: " + orig);
    System.out.println("unc:  " + uncompressedStr);
于 2013-01-22T20:06:49.217 に答える
4

Joopには解決策があるようですが、これを追加する必要があると思います。一般的には圧縮、特にGZIPはバイナリストリームを生成します。この ストリームから文字列を作成しようとしてはいけません-それは壊れます

プレーンテキスト表現にする必要がある場合は、Base64エンコーディング、16進エンコーディング、一体、さらには単純なバイナリエンコーディングを調べてください。

要するに、Stringオブジェクトは人間が読むもののためのものです。バイト配列(および他の多くのもの)は、マシンが読み取るもののためのものです。

于 2013-01-22T20:23:39.620 に答える
0

デフォルトのプラットフォーム エンコーディング (おそらく UTF-8) を使用して、baostream を文字列にエンコードしました。文字列ではなくバイナリ データを操作するには、baostream.getBytes() を使用する必要があります。

文字列に固執する場合は、8 ビットのエンコーディング、つまり baostream.toString("ISO-8859-1") を使用し、同じ文字セットで読み戻してください。

于 2013-01-22T19:55:21.660 に答える