5

コードに問題があります:

private static String compress(String str)
{
    String str1 = null;
    ByteArrayOutputStream bos = null;
    try
    {
        bos = new ByteArrayOutputStream();
        BufferedOutputStream dest = null;

        byte b[] = str.getBytes();
        GZIPOutputStream gz = new GZIPOutputStream(bos,b.length);
        gz.write(b,0,b.length);
        bos.close();
        gz.close();

    }
    catch(Exception e) {
        System.out.println(e);
        e.printStackTrace();
    }
    byte b1[] = bos.toByteArray();
    return new String(b1);
}

private static String deCompress(String str)
{
    String s1 = null;

    try
    {
        byte b[] = str.getBytes();
        InputStream bais = new ByteArrayInputStream(b);
        GZIPInputStream gs = new GZIPInputStream(bais);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int numBytesRead = 0;
        byte [] tempBytes = new byte[6000];
        try
        {
            while ((numBytesRead = gs.read(tempBytes, 0, tempBytes.length)) != -1)
            {
                baos.write(tempBytes, 0, numBytesRead);
            }

            s1 = new String(baos.toByteArray());
            s1= baos.toString();
        }
        catch(ZipException e)
        {
            e.printStackTrace();
        }
    }
    catch(Exception e) {
        e.printStackTrace();
    }
    return s1;
}

public String test() throws Exception
    {
        String str = "teststring";
        String cmpr = compress(str);
        String dcmpr = deCompress(cmpr);
}

このコードは java.io.IOException: unknown format (マジック ナンバー ef1f) をスローします。

GZIPInputStream gs = new GZIPInputStream(bais);

new String (b1)バイトを変換すると、byte b [] = str.getBytes ()バイトが「損なわれる」ことが判明しました。行の出力では、すでにバイト数が増えています。文字列への変換を回避し、バイトを含む行で作業すると、すべてが機能します。私の英語でごめんなさい。


public String unZip(String zipped) throws DataFormatException, IOException {
    byte[] bytes = zipped.getBytes("WINDOWS-1251");
    Inflater decompressed = new Inflater();
    decompressed.setInput(bytes);

    byte[] result = new byte[100];
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    while (decompressed.inflate(result) != 0)
        buffer.write(result);

    decompressed.end();

    return new String(buffer.toByteArray(), charset);
}

この関数を使用して、サーバーの応答を解凍しています。手伝ってくれてありがとう。

4

3 に答える 3

8

2つの問題があります。

  • デフォルトの文字エンコードを使用して、元の文字列をバイトに変換しています。それはプラットフォームによって異なります。エンコーディングを指定することをお勧めします-通常、UTF-8は良い考えです。
  • String(byte[])コンストラクターを呼び出すだけで、圧縮結果の不透明なバイナリデータを文字列として表現しようとしています。そのコンストラクターは、エンコードされたテキストであるデータのみを対象としています...これはそうではありません。これにはbase64を使用する必要があります。これを簡単にするパブリックドメインのbase64ライブラリがあります。(または、圧縮データをテキストに変換しないでください。バイト配列を返すだけです。)

基本的に、テキストとバイナリデータの違いを理解する必要があります。2つの間で変換する場合は、慎重に行う必要があります。「非テキスト」バイナリデータ(つまり、テキストのエンコードの直接の結果ではないバイト)を文字列で表現する場合は、base64やhexなどを使用する必要があります。文字列をバイナリデータとしてエンコードする場合(たとえば、ディスクにテキストを書き込む場合)、使用するエンコードを慎重に検討する必要があります。別のプログラムがデータを読み取る場合は、そのプログラムが期待するエンコーディングを理解する必要があります。自分で完全に制御できる場合は、通常、UTF-8を使用します。

さらに、コードでの例外処理は不十分です。

  • あなたはほとんど決して捕まえるべきではありませんException; より具体的な例外をキャッチする
  • 例外をキャッチして、それが発生したことがないかのように続行するべきではありません。例外を実際に処理できず、メソッドを正常に完了することができない場合は、例外をスタックにバブルアップさせる必要があります(または、例外をキャッチして、抽象化に適した例外タイプでラップする必要があります)。
于 2012-06-11T05:54:47.063 に答える
2

データをGZIP圧縮すると、常にバイナリデータが取得されます。このデータは(どのエンコーディングでも)有効な文字データではないため、文字列に変換できません。

したがって、compressメソッドはバイト配列を返し、decompressメソッドはパラメーターとしてバイト配列を受け取る必要があります。

さらに、圧縮前に文字列をバイト配列に変換するとき、および解凍されたデータを再び文字列に変換するときは、明示的なエンコードを使用することをお勧めします。

于 2012-06-11T05:55:16.267 に答える
0

データを GZIP 圧縮すると、常にバイナリ データが得られます。このデータは有効な文字データではないため (どのエンコーディングでも)、文字列に変換できません。

コドは正しいです、私を啓発してくれてありがとう。文字列(バイナリデータから変換)を解凍しようとしていました。私が修正したのは、http 接続によって返された入力ストリームで InflaterInputStream を直接使用することでした。(私のアプリは文字列の大きな JSON を取得していました)

于 2013-08-07T02:45:47.770 に答える