2017-06-17 36 views
2

私は現在、DuckDuckGoアイコンユーティリティを使用して特定のWebページのファビコンを取得していますが、アイコンを取得するには、リクエストの最後に「.ico」を追加する必要がありますたとえば、https://icons.duckduckgo.com/ip2/www.google.com.icoDuckDuckGoから.icoファイルをダウンロード

したがって、私はWebClientを使用してfaviconをダウンロードしていますが、ファイルを開くたびに、破損していると表示され、「ファイルのヘッダーを読み取ることができません」というエラーがスローされて以来、完全にダウンロードされていないようです。

私が試したこれまでのところ、以下の(私のWebClientclientと呼ばれ、設定するためのアイコンがfaviconと呼ばれ、アイコンファイルへのパスが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); 

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_urlの複数のピリオド('.')が原因であると推測していますので、私の質問は次のとおりです。その名前にピリオドが複数ある場合は、WebClient(または類似のもの)ですか?期間がない場合は、なぜDuckDuckGoからダウンロードしたファイルを読むことができないのですか?

+0

_「私は複数の期間favicon_urlでは責任があると推測している(。)」:しかし、このアプローチは、中間ファイルを必要とせずに、データがIconオブジェクトにリモートサーバから直接読み取ることができるようになります_それは私には非常に貧弱な推測のように聞こえる。 URLが有効であるかそうでないかのいずれかです。そうでない場合は、無効なデータではなくHTTPリクエストにエラーが発生します。私は、Webサイトが実際のWindowsアイコンファイルをアイコンとして使用していないことが大きな問題であると考えています。それらは実際にはビットマップであり、そのように読む必要があります。ダウンロードしたファイルを 'Icon'コンストラクタに渡そうとしているようですが、実際には有効な.icoファイルではありません(Webサイトの拡張機能にもかかわらず)。 –

+0

複数の期間は問題ではありません。ダウンロードしたファイルをメモ帳などのテキストエディタで開き、保存されているバイナリファイルであることを確認できますか?おそらく保存されているHTMLエラーページです。 – James

+0

'favicon_url.ToString()'は何を返しますか? 'https:// icons.duckduckgo.com/ip2/www.google.com.ico'を使ってテストすれば、コードは動作しますか? – mjwills

答えて

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オブジェクトでサポートされていません(明らかな理由により)。したがって、オブジェクトにデータを解凍する必要があります。です。

HttpWebRequestを使用する代替ソリューションがあります。は、がダウンロード中にサポートされています。これはの代わりにであり、上記の他の例と同じではなく、WebClient.DownloadFile()です。

最初に中間バッファにコピーする必要があります(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); 
+0

私はテスト(youtube.com)として使っているウェブサイトは、拡張子がアイコンのように表示されるように名前が変更された「ショートカットアイコン」としてPNGが設定されています。だから私は、PNGファイルを品質を失うことなくアイコンに変換する私の他の選択肢に戻らなければならないだろう。とにかく、ありがとう! –

関連する問題