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();
}
}
精彩评论