开发者

Decompress string in c# which were compressed by php's gzcompress()

i'm querying a webservice in c# 4.0, which provides me with a string compressed by php's gzcompress(). Now i need to decompress this string in c#. I tried several ways including

  • GZipStream decompression performance is poor
  • C# to Java: Base64String, MemoryStream, GZipStream
  • How to solve Gzip Magic Number Missing

but everytime i get an "Missing Magic Number" exception.

Can someone provide me with some hints?

Thank you

Edit 1:

My latest try:

public static string Decompress(string compressed) {
    byte[] compressedBytes = Encoding.ASCII.GetBytes(compressed);
    MemoryStream mem = new 开发者_开发知识库MemoryStream(compressedBytes);
    GZipStream gzip = new GZipStream(mem, CompressionMode.Decompress);
    StreamReader reader = new StreamReader(gzip);
    return reader.ReadToEnd();
}


Well, there you go, with a little help from @boas.anthro.mnsu.edu:

using (var mem = new MemoryStream())
{
    mem.Write(new byte[] { 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0, 8);
    mem.Write(inputBytes, 0, inputBytes.Length);

    mem.Position = 0;

    using (var gzip = new GZipStream(mem, CompressionMode.Decompress))
    using (var reader = new StreamReader(gzip))
    {
        Console.WriteLine(reader.ReadToEnd());
    }
}

The trick is to add a magic header. Note that this does not work with SharpZipLib. It complains that there is not footer. However, the .NET decompresser works perfectly.

One more thing. The comment concerning the ASCII.GetBytes() is correct: your input isn't ASCII. I achieved this result with the following:

// From PHP:

<?php echo base64_encode(gzcompress("Hello world!")); ?>

// In C#:

string input = "eJzzSM3JyVcozy/KSVEEAB0JBF4=";

byte[] inputBytes = Convert.FromBase64String(input);

With the extra base64 encoding and decoding, this works perfectly.

If you can't use base64 encoding, you need the raw stream from the PHP page. You can get this using the GetResponseStream():

 var request = WebRequest.Create("http://localhost/page.php");

 using (var response = request.GetResponse())
 using (var mem = response.GetResponseStream())
 {
     // Decompression code from above.
 }


I want to extend Peter's answer. PHP also may compress with Deflate algorithm. In this case you should use DeflateStream instead of GZipStream and remove first 2 bytes (HEX: 78 9C) DeflateStream not working with buffer processed from PHP implementation

 private static byte[] Decompress(byte[] data)
{
  using (var compressedStream = new MemoryStream(data.Skip(2).ToArray()))
  using (var zipStream = new DeflateStream(compressedStream, CompressionMode.Decompress))
  using (var resultStream = new MemoryStream())
  {
    zipStream.CopyTo(resultStream);
    return resultStream.ToArray();
  }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜