C#中的Gzip压缩和解压缩 [英] Gzip compression and decompression in C#

查看:83
本文介绍了C#中的Gzip压缩和解压缩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在一个模块中压缩字符串,然后在另一模块中将其解压缩.这是我正在使用的代码.

压缩

 公共静态字符串CompressString(字符串文本){byte [] buffer = Encoding.ASCII.GetBytes(text);MemoryStream ms =新的MemoryStream();使用(GZipStream zip = new GZipStream(ms,CompressionMode.Compress,true)){zip.Write(buffer,0,buffer.Length);}ms.Position = 0;MemoryStream outStream =新的MemoryStream();byte []压缩=新的byte [ms.Length];ms.Read(compressed,0,compression.Length);byte [] gzBuffer =新的byte [compressed.Length + 4];System.Buffer.BlockCopy(compressed,0,gzBuffer,4,compression.Length);System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length),0,gzBuffer,0,4);返回Convert.ToBase64String(gzBuffer);} 

解压缩

 公共静态字节[] DecompressString(字节[]数据){使用(var compressionStream = new MemoryStream(data))使用(var zipStream = new GZipStream(compressedStream,CompressionMode.Decompress))使用(var resultStream = new MemoryStream()){zipStream.CopyTo(resultStream);返回resultStream.ToArray();}} 

用作:

  DecompressString(System.Text.Encoding.ASCII.GetBytes(ip)); 

但是,对于以上声明,我遇到以下错误.

{"GZip标头中的幻数不正确.请确保您是传入GZip流.} System.SystemException{System.IO.InvalidDataException}

解决方案

这里是对代码的重写,应该可以按照您希望的方式工作.

我在 LINQPad 中编写了它,并可以在其中进行测试.

请注意,这里几乎没有错误检查.您应该添加检查以查看所有读取操作是否已完成,并且已经实际读取了它们应该执行的操作以及类似的检查.

输出

 原件:256这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.压缩的:56AAEAAB + LCAAAAAAABAALycgsVgCiRIWS1OISPYWQEcYHANU9d5YAAQAA解压后:256这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试.这是一个测试. 

程序

  void Main(){var input =这是一个测试.这是一个测试.";输入+ =输入;输入+ =输入;输入+ =输入;字符串压缩= Compress(输入);字符串解压缩=解压缩(压缩);input.Dump("original:" + input.Length);compression.Dump("compressed:" + compression.Length);decompressed.Dump("decompressed:" + decompressed.Length);}公共静态字符串解压缩(字符串输入){byte []压缩= Convert.FromBase64String(input);byte [] decompressed = Decompress(compressed);返回Encoding.UTF8.GetString(已解压缩);}公共静态字符串Compress(字符串输入){byte []编码= Encoding.UTF8.GetBytes(input);byte []压缩=压缩(编码);返回Convert.ToBase64String(compressed);}公共静态字节[]解压缩(字节[]输入){使用(var source = new MemoryStream(input)){byte [] lengthBytes =新的byte [4];source.Read(lengthBytes,0,4);var length = BitConverter.ToInt32(lengthBytes,0);使用(var decompressionStream = new GZipStream(source,CompressionMode.Decompress)){var result = new byte [length];decompressionStream.Read(result,0,length);返回结果;}}}公共静态字节[]压缩(字节[]输入){使用(var result = new MemoryStream()){var lengthBytes = BitConverter.GetBytes(input.Length);result.Write(lengthBytes,0,4);使用(var compressionStream = new GZipStream(result,CompressionMode.Compress)){compressionStream.Write(input,0,input.Length);compressionStream.Flush();}返回result.ToArray();}} 

I'm trying to compress an string in one module and decompressing it in another module. Here is the code I'm using.

Compress

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);
}

Decompress

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();
     }
}

Using it as:

 DecompressString(System.Text.Encoding.ASCII.GetBytes(ip));

But, for above statement, I'm getting following error.

{"The magic number in GZip header is not correct. Make sure you are passing in a GZip stream."} System.SystemException {System.IO.InvalidDataException}

解决方案

Here is a rewrite of your code that should work the way you want it to.

I wrote it in LINQPad and it can be tested in that.

Note that there's very little error checking here. You should add checks to see if all read operations complete and has actually read what they were supposed to and similar checks.

The output

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.  

The program

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();
    }
}

这篇关于C#中的Gzip压缩和解压缩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆