2012-01-26 32 views
4

在獲得一些隨機西班牙報紙的索引正確使用的WebRequest我不明白的發音符號,它們產生這種怪異的性格:,同時採用了WebClient我得到相應的響應下載來自同一個URI的響應。使用WebClient和WebRequest編碼區別?

爲什麼這種差異?

var client = new WebClient(); 
string html = client.DownloadString(endpoint); 

VS

WebRequest request = WebRequest.Create(endpoint); 
using (WebResponse response = request.GetResponse()) 
{ 
    Stream stream = response.GetResponseStream(); 
    StreamReader reader = new StreamReader(stream); 
    string html = reader.ReadToEnd(); 
} 
+0

我猜測,但它可能是因爲'WebClient.DownloadString'着眼於'內容type'管器(例如「text/html的;字符集= UTF-16」)來推斷編碼,但您的WebRequest方法使用UTF8(StreamReader的默認值) – spender

+0

在這種情況下,'content-type'頭文件沒有指定字符集。 – bevacqua

+0

@Nico。然後,它應該做的測試爲UTF-8,UTF-16LE,UTF-16BE和UTF-32根據預先同步碼(檢測BOM和其他告訴-故事),最後將默認爲默認遺留字符集,這恰好匹配您的機器上的網站。由於HTTP假設拉丁-1(畢竟,這是90年代初),它可能是明智地使用,作爲你的「我不知道」的選擇。 –

回答

4

你只是假設,如果沒有明確設置編碼創建流閱讀器當實體是UTF-8。你應該檢查HttpWebResponse(不是由WebResponse基類暴露)的CharacterSet,並用適當的編碼打開StreamReader。否則,如果它讀取的內容不是UTF-8,就好像它是UTF-8一樣,它會遇到在UTF-8中無效的八位字節序列,並且必須替換爲U + FFFD替換字符()盡其所能。

Web客戶端確實非常的:DownloadString是一個更高層次的方法,即在那裏WebRequest及其派生類讓你在較低的獲得,它有一個單一的喊出了「發送GET請求的URI,檢查頭,看看什麼樣的內容編碼在使用,如果你需要取消的gzip或解壓縮它,看到的是什麼字符編碼到位,建立一個文本閱讀器與編碼和流,然後調用ReadAll()」。正常的高級別大塊指令與低級別小塊指令的優缺點相關。

+0

另外,如果你想反映什麼'WebClient'專門確實改變了'StreamReader'到'StreamReader的讀者=新的StreamReader(流,System.Text.Encoding.Default)' –

+0

@ChrisHaas不,不,那會甚至更糟 - 儘管它可能在這種情況下工作 - 因爲它可以用於一個傳統編碼,但不適用於UTF-8。它檢查標題並設置正確的 - 這可能與System.Text.Encoding.Default相同,但很可能不會。如果頭文件沒有明確請求字符集,它會按順序嘗試UTF-8,UTF-16LE,UTF-16BE和UTF-32,看看結果是否有意義。最後如果失敗,它使用它自己的'Encoding'屬性。 –

+0

@ChrisHaas授予,如果它沒有找到一個BOM或一個零八位字節使遊戲離開,並且沒有顯式設置'Encoding',那麼會導致使用'System.Text.Encoding.Default' 。 –