我在c#4.0中查询一个web服务,它为我提供了一个由php gzcompress()压缩的字符串。现在我需要在c#中解压缩这个字符串。我试过几种方法,包括
但每次我都会收到“遗失魔法数字”的例外情况。
有人能给我提供一些提示吗?
谢谢
修改1:
我的最新尝试:
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();
}
答案 0 :(得分:11)
嗯,你去了@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());
}
}
诀窍是添加魔术头。请注意,使用SharpZipLib时,无效。它抱怨说没有页脚。但是,.NET解压缩程序运行得很好。
还有一件事。有关ASCII.GetBytes()
的注释是正确的:您的输入不是ASCII。我用以下方法实现了这个结果:
// From PHP:
<?php echo base64_encode(gzcompress("Hello world!")); ?>
// In C#:
string input = "eJzzSM3JyVcozy/KSVEEAB0JBF4=";
byte[] inputBytes = Convert.FromBase64String(input);
使用额外的base64编码和解码,这非常有效。
如果您不能使用base64编码,则需要PHP页面中的原始流。您可以使用GetResponseStream()
:
var request = WebRequest.Create("http://localhost/page.php");
using (var response = request.GetResponse())
using (var mem = response.GetResponseStream())
{
// Decompression code from above.
}
答案 1 :(得分:0)
我想扩大彼得的回答。 PHP也可以使用Deflate算法压缩。在这种情况下,您应该使用DeflateStream而不是GZipStream并删除前2个字节(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();
}
}