C# C语言中的Gzip压缩与解压缩#

C# C语言中的Gzip压缩与解压缩#,c#,gzip,C#,Gzip,我试图在一个模块中压缩字符串,然后在另一个模块中解压缩它。这是我正在使用的代码 压缩 public static string CompressString(string text) { byte[] buffer = Encoding.ASCII.GetBytes(text); MemoryStream ms = new MemoryStream(); using (GZipStream zip = new GZipStream(ms, CompressionMode.

我试图在一个模块中压缩字符串,然后在另一个模块中解压缩它。这是我正在使用的代码

压缩

public static string CompressString(string text)
{
    byte[] buffer = Encoding.ASCII.GetBytes(text);
    MemoryStream ms = new MemoryStream();
    using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
    {
         zip.Write(buffer, 0, buffer.Length);
    }

    ms.Position = 0;
    MemoryStream outStream = new MemoryStream();

    byte[] compressed = new byte[ms.Length];
    ms.Read(compressed, 0, compressed.Length);

    byte[] gzBuffer = new byte[compressed.Length + 4];
    System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
    System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);
    return Convert.ToBase64String(gzBuffer);
}
减压

public static byte[] DecompressString(byte[] data)
{
   using (var compressedStream = new MemoryStream(data))
   using (var zipStream = new GZipStream(compressedStream, CompressionMode.Decompress))
     using (var resultStream = new MemoryStream())
     {
        zipStream.CopyTo(resultStream);
        return resultStream.ToArray();
     }
}
将其用作:

 DecompressString(System.Text.Encoding.ASCII.GetBytes(ip));
但是,对于上面的陈述,我得到了以下错误

{“GZip头中的幻数不正确。请确保正确 正在传递GZip流。“}System.SystemException {System.IO.InvalidDataException}


下面是对代码的重写,它应该按照您希望的方式工作

我写的,可以用它来测试

注意,这里几乎没有错误检查。您应该添加检查,以查看是否所有读取操作都已完成,并且实际读取了它们应该读取的内容和类似的检查

输出

original: 256
This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test.  

compressed: 56
AAEAAB+LCAAAAAAABAALycgsVgCiRIWS1OISPYWQEcYHANU9d5YAAQAA 

decompressed: 256
This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test. This is a test.  
节目

void Main()
{
    var input = "This is a test. This is a test. ";
    input += input;
    input += input;
    input += input;
    string compressed = Compress(input);
    string decompressed = Decompress(compressed);

    input.Dump("original: " + input.Length);
    compressed.Dump("compressed: " + compressed.Length);
    decompressed.Dump("decompressed: " + decompressed.Length);
}

public static string Decompress(string input)
{
    byte[] compressed = Convert.FromBase64String(input);
    byte[] decompressed = Decompress(compressed);
    return Encoding.UTF8.GetString(decompressed);
}

public static string Compress(string input)
{
    byte[] encoded = Encoding.UTF8.GetBytes(input);
    byte[] compressed = Compress(encoded);
    return Convert.ToBase64String(compressed);
}

public static byte[] Decompress(byte[] input)
{
    using (var source = new MemoryStream(input))
    {
        byte[] lengthBytes = new byte[4];
        source.Read(lengthBytes, 0, 4);

        var length = BitConverter.ToInt32(lengthBytes, 0);
        using (var decompressionStream = new GZipStream(source,
            CompressionMode.Decompress))
        {
            var result = new byte[length];
            decompressionStream.Read(result, 0, length);
            return result;
        }
    }
}

public static byte[] Compress(byte[] input)
{
    using (var result = new MemoryStream())
    {
        var lengthBytes = BitConverter.GetBytes(input.Length);
        result.Write(lengthBytes, 0, 4);

        using (var compressionStream = new GZipStream(result,
            CompressionMode.Compress))
        {
            compressionStream.Write(input, 0, input.Length);
            compressionStream.Flush();

        }
        return result.ToArray();
    }
}

嗯,您正在对压缩结果进行base64编码,但在解压缩之前没有对其进行解码?确实-
DecompressString(Convert.FromBase64String(ip))会更有意义。(尽管我也建议您的方法应该是对称的,例如,让它们同时接受和返回字符串,或者可能是
byte[]Compress(string)
string Decompress(byte[]))
。此外,如果要在这些字节的开头填充压缩数据的长度,则还需要在解压缩之前删除这些字节。此外,存储未压缩数据的长度更有意义,以便在解压缩结束时处理一些小问题。请注意,我不确定是否需要写出这些字节压缩数据之前未压缩数据的长度。使用某些压缩方法,如果您试图读取比压缩时更多的数据,则最后一个字节或代码可能会被解释为更多的数据,这是由于存在剩余位,但我不确定这是否适用于gzip,因此该部分可能是不必要的。事实上,通过从1到1000 ad填充进行测试输入末尾的附加字符似乎表明不需要这样做。不过,了解gzip的人必须对此进行评论。