从DuckDuckGo下载.ico文件

时间:2017-06-17 06:17:18

标签: c# .net winforms

我目前正在使用DuckDuckGo图标工具来获取某些网页的图标,但是为了获取图标,它需要您在请求的最后添加“.ico”,例如:{{3 }}

所以,我正在使用WebClient下载favicon,但是;它似乎没有完全下载它,因为每次打开文件时它都显示已损坏并抛出错误,指出“文件头无法读取”。

到目前为止,我已尝试过以下内容(我的WebClient被称为client,要设置的图标称为favicon,图标文件的路径称为{{1} }):

favicon_path

Uri favicon_url = new Uri(
    "https://icons.duckduckgo.com/ip2/" + gBrowser.Url.Host.ToString() + ".ico");
client.DownloadFile(@favicon_url, favicon_path);
favicon = new Icon(favicon_path);

我猜测 favicon_url 中的多个句点(Uri favicon_url = new Uri("https://icons.duckduckgo.com/ip2/" + gBrowser.Url.Host.ToString().Replace(".", "%2E") + ".ico"); client.DownloadFile(@favicon_url, favicon_path); favicon = new Icon(favicon_path); )是有责任的,所以我的问题是:如何使用'.'下载favicon(或类似的东西)如果它的名字有多个句号?或者如果不是句号,为什么我不能读取从DuckDuckGo下载的文件?

1 个答案:

答案 0 :(得分:1)

好的,这是你需要做的事情(在致电DownloadFile()之后):

using (Stream inputStream = File.OpenRead(favicon_path))
using (Stream gzipStream = new GZipStream(inputStream, CompressionMode.Decompress))
{
    MemoryStream copyStream = new MemoryStream();

    gzipStream.CopyTo(copyStream);
    copyStream.Position = 0;

    favicon = new Icon(copyStream);
}

我注意到下载的文件比实际的.ico文件小得多。这表明数据正以某种方式被压缩。 Gzip是事实上的跨平台流压缩格式,所以我做了一个猜测并尝试解压缩数据,好像它是用gzip压缩的。果然,确实如此。

请注意,您需要先将数据解压缩到中间缓冲区(我使用了MemoryStream个对象)。 Icon构造函数将尝试查找GzipStream对象不支持的流(出于显而易见的原因)。因此,您需要将数据解压缩为 可搜索的Stream对象。

另请注意,有一个使用HttpWebRequest的替代解决方案, 支持在下载期间进行解压缩。这是而不是使用WebClient.DownloadFile(),而不是像上面的其他示例中那样。

您仍然必须首先复制到中间缓冲区(同样,因为Icon想要寻找不可搜索的源流)。但是这种方法允许直接从远程服务器读取数据到Icon对象,而不需要中间文件:

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(favicon_url);

// You can also include `DecompressionMethods.Deflate` here, for a more general solution
request.AutomaticDecompression = DecompressionMethods.GZip;

MemoryStream copyStream = new MemoryStream();

request.GetResponse().GetResponseStream().CopyTo(copyStream);
copyStream.Position = 0;
favicon = new Icon(copyStream);