1

次のコードを使用して 2 つの文字列を圧縮していますが、圧縮に適しています。ただし、2 番目の文字列を解凍しようとすると、最初の文字列が短い場合 (約 4 文字)、Block length does not match with its Complement exception が発生します。圧縮に使用したクラスは次のとおりです。

    using System;
    using System.IO;
    using System.IO.Compression;
    using System.Text;

    namespace CompressString {
    internal static class StringCompressor
{
    /// <summary>
    /// Compresses the string.
    /// </summary>
    /// <param name="text">The text.</param>
    /// <returns></returns>
    public static string CompressString(string value)
    {
        //Transform string into byte[] 
        byte[] byteArray = new byte[value.Length];
        int indexBA = 0;
        foreach (char item in value.ToCharArray())
        {
            byteArray[indexBA++] = (byte)item;
        }

        //Prepare for compress
        System.IO.MemoryStream ms = new System.IO.MemoryStream();
        System.IO.Compression.GZipStream sw = new System.IO.Compression.GZipStream(ms,
        System.IO.Compression.CompressionMode.Compress);

        //Compress
        sw.Write(byteArray, 0, byteArray.Length);
        //Close, DO NOT FLUSH cause bytes will go missing...
        sw.Close();

        //Transform byte[] zip data to string
        byteArray = ms.ToArray();
        System.Text.StringBuilder sB = new System.Text.StringBuilder(byteArray.Length);
        foreach (byte item in byteArray)
        {
            sB.Append((char)item);
        }
        ms.Close();
        sw.Dispose();
        ms.Dispose();

        return sB.ToString();
    }

    /// <summary>
    /// Decompresses the string.
    /// </summary>
    /// <param name="compressedText">The compressed text.</param>
    /// <returns></returns>
    public static string DecompressString(string sData)
    {
        byte[] byteArray = new byte[sData.Length];

        int indexBa = 0;
        foreach (char item in sData)
            byteArray[indexBa++] = (byte)item;

        MemoryStream memoryStream = new MemoryStream(byteArray);
        GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress);

        byteArray = new byte[1024];

        StringBuilder stringBuilder = new StringBuilder();

        int readBytes;
        while ((readBytes = gZipStream.Read(byteArray, 0, byteArray.Length)) != 0)
        {
            for (int i = 0; i < readBytes; i++) stringBuilder.Append((char)byteArray[i]);
        } gZipStream.Close(); memoryStream.Close(); gZipStream.Dispose(); memoryStream.Dispose(); return stringBuilder.ToString();
    }
}

}

次の行の DecompressString メソッドで例外が発生しました。

while ((readBytes = gZipStream.Read(byteArray, 0, byteArray.Length)) != 0)
4

3 に答える 3

2

「ブロックの長さがその補数と一致しません」というエラー メッセージが表示される場合は、圧縮されていないファイルを解凍しようとすると発生する可能性があります。

于 2015-02-23T20:53:13.887 に答える
1

Compress メソッドと Decompress メソッドは、バイト配列を受け入れて返す必要があります。その後、文字列出力を生成する必要がある場合は、バイト配列を base64 文字列に変換できます。

例えば:

// compress some string data
string stringData = GetSomeStringData();

// assumes the string data is UTF8 string - would work for ASCII encoding as well
byte[] uncompressedData = Encoding.UTF8.GetBytes(stringData);

byte[] compressedData = StringCompressor.Compress(uncompressedData);

// produce base64 encode string of compressed data
string compressedString = Convert.ToBase64String(compressedData);

// decompress base64 encoded string 
// first convert to byte array
byte[] dataToDecompress = Convert.FromBase64String(compressedString);

byte[] decompressedData = StringCompressor.Decompress(dataToDecompress);

// encode decompressed data as a UTF8 encoded string
string decompressedString = Encoding.UTF8.GetString(decompressedData);

それに応じて Compress() および Decompress() メソッドの名前を変更し、微調整します。文字列を厳密に処理するクラスが本当に必要な場合は、Base 64 エンコード/デコードのロジックをメソッドに埋め込みます。ただし、クラスが直接 'byte[]` で動作する場合、コードはより柔軟になり、他のインスタンスで再利用可能になります。

于 2013-04-25T13:39:22.553 に答える
1

同じ「ブロックの長さが補数と一致しません。」System.IO.InvalidDataException.

この情報を見つけました: http://yvanrodrigues.com/content/block-length-does-not-match-its-complement

「最初に 2 バイトをシークします。圧縮されたファイルの先頭に 2 バイトの署名 0x789c があります。」

これらの 2 バイトをスキップすると機能するはずです。

詳細情報: zlib ヘッダーはどのようなものですか? および .Net zlib inflate with .Net 4.5

于 2016-08-30T06:48:27.260 に答える