我有以下代码:
var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/test.xml.gz");
request.UserAgent = "TEST";
request.Accept = "*/*";
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
var response = (HttpWebResponse)request.GetResponse();
var stream = response.GetResponseStream();
var buffer = new byte[4096];
int read;
if (File.Exists("test.txt"))
File.Delete("test.txt");
var file = new FileStream("test.txt", FileMode.CreateNew);
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
file.Write(buffer, 0, read);
file.Close();
stream.Dispose();
当我在Windows上运行它时,我将文件解压缩到8M。当我在Mono上运行它时,test.txt是521K的压缩数据。
我正在使用从tarball编译的Mono 3.2.6。 (安装在/ usr / local / lib下的Debian 7.3上的编辑:)
我做错了什么,或Mono目前不支持此功能?
答案 0 :(得分:0)
我似乎支持自动解压缩,但the implementation solely depends on the headers sent by the server。在我的特定情况下,我正在尝试抓取一个糟糕的网站,即使响应被压缩,也不会发送正确的内容编码。我的猜测是,典型MS时尚的MS impl试图超越标题检查,并且可能会增加GZ魔法前两个字节等。
无论如何,对于未来可能会发现自己处于这个位置的人来说,这是我的解决方案:
var request = (HttpWebRequest)WebRequest.Create("http://www.example.com/test.xml.gz");
request.Accept = "*/*";
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
var response = (HttpWebResponse)request.GetResponse();
var mem = new MemoryStream() as Stream;
using (var stream = response.GetResponseStream())
stream.CopyTo(mem);
var bytes = (mem as MemoryStream).GetBuffer();
if (bytes[0] == '\x1F' && bytes[1] == '\x8B')
{
mem.Position = 0;
mem = new GZipStream(mem, CompressionMode.Decompress);
var uncompressed = new MemoryStream(bytes.Length * 20);
mem.CopyTo(uncompressed);
mem.Dispose();
mem = uncompressed;
}
if (File.Exists("lala.txt"))
File.Delete("lala.txt");
var file = new FileStream("lala.txt", FileMode.CreateNew);
mem.Position = 0;
mem.CopyTo(file);
file.Close();
(注意:我在这里没有正确处理所有内容,这只是示例代码。)