2013-07-27 25 views
3

這是第一個出現問題的維基頁面。當我使用HttpWebResponse.GetResponseStream()打開這個頁面https://en.wikipedia.org/wiki/London時,它充滿了mojibake。但我的瀏覽器可以毫無問題地編碼它。奇怪的維基百科mojibake(錯誤編碼)

我已經使用了三種方法來下載文本文件。他們都獲得不同的文件。

第一種方法下載的274851個字節

string TargetUri = "https://en.wikipedia.org/wiki/London"; 

    HttpWebRequest queryPage = (HttpWebRequest)WebRequest.Create(TargetUri); 

    queryPage.Credentials = CredentialCache.DefaultCredentials; 

    using (HttpWebResponse response = (HttpWebResponse)queryPage.GetResponse()) 
    { 

     using (Stream PageRawCode = response.GetResponseStream()) 
     { 
      using (MemoryStream PageRawCodeDuplicate = new MemoryStream()) 
      { 
       byte[] buffer = new byte[1024]; 
       int ByteCount; 
       do 
       { 
        ByteCount = PageRawCode.Read(buffer, 0, buffer.Length); 
        PageRawCodeDuplicate.Write(buffer, 0, ByteCount); 
       } while (ByteCount > 0); 

       PageRawCodeDuplicate.Seek(0, SeekOrigin.Begin); 

       using (StreamReader CodeInUTF8 = new StreamReader(PageRawCodeDuplicate)) 
       { 
        string PageText = CodeInUTF8.ReadToEnd(); 
        using (StreamWriter sw = new StreamWriter(@"E:\My Documents\Desktop\london1.html")) 
        { 
         sw.Write(PageText); 
        } 
       } 
      } 
     } 
    } 

一個文件中的第二方法是

WebClient myWebClient = new WebClient(); 
    myWebClient.DownloadFile("https://en.wikipedia.org/wiki/London", @"E:\My Documents\Desktop\london2.html"); 

此方法僅下載的152.297個字節

文件

第三種方法是打開https://en.wikipedia.org/wiki/London,並保存源代碼文件。這種方法將得到一個文件的1746,420字節

我不明白爲什麼有一個這樣的區別使用不同的方法獲取文本文件。

我已經使用ASCII,BigEndianUnicode,Unicode,UTF32,UTF7,UTF8來讀取前兩個文件。他們都沒有正確顯示代碼。

然後我讀取文件的十六進制代碼。 london1.html的前32個字符是

1FEFBFBD0800000000000003EFBFBDEF 

london2.html的前32個字符是

1F8B0800000000000003ECFD4B8F1C49 

顯然他們不是<!DOCTYPE html>

什麼是這兩個文件?我甚至不知道如何檢查它們。

回答

0

在代碼中存在一個簡單的問題。你忘記刷新內存流了。我還補充說,不首先在內存中拷貝流的第二個解決方案......

如果我運行此稍作改動代碼,我得到一個完整的HTML文件:

using (HttpWebResponse response = (HttpWebResponse)queryPage.GetResponse()) 
{ 

    using (Stream PageRawCode = response.GetResponseStream()) 
    { 
     using (MemoryStream PageRawCodeDuplicate = new MemoryStream()) 
     { 
      byte[] buffer = new byte[1024]; 
      int ByteCount; 
      do 
      { 
       ByteCount = PageRawCode.Read(buffer, 0, buffer.Length); 
       PageRawCodeDuplicate.Write(buffer, 0, ByteCount); 
      } while (ByteCount > 0); 

      // FLUSH! 
      PageRawCodeDuplicate.Flush(); 

      PageRawCodeDuplicate.Seek(0, SeekOrigin.Begin); 

      // Pick an encoding here 
      using (StreamReader CodeInUTF8 = new StreamReader(
            PageRawCodeDuplicate, Encoding.UTF8)) 
      { 
       string PageText = CodeInUTF8.ReadToEnd(); 
       using (StreamWriter sw = new StreamWriter(@"london1.html")) 
       { 
        sw.Write(PageText); 
       } 
      } 
     } 
    } 
} 

直接複製的流

using (HttpWebResponse response = (HttpWebResponse)queryPage.GetResponse()) 
{ 
    using (Stream PageRawCode = response.GetResponseStream()) 
    { 
      using (StreamReader CodeInUTF8 = new StreamReader(
                 PageRawCode, Encoding.UTF8)) 
      { 
       using (StreamWriter sw = new StreamWriter(@"london1.html")) 
       { 
        while (!CodeInUTF8.EndOfStream) 
        { 
         sw.WriteLine(CodeInUTF8.ReadLine()); 
        } 
       } 
      } 
    } 
} 
+0

謝謝你的回答。但是我現在還不能證明您的解決方案,因爲頁面偶爾會出現問題,但並非總是如此。它在這一刻起作用。 –

+0

無論你是否沖洗都沒關係。它不起作用。如果你有興趣,請嘗試http://en.wikipedia.org/wiki/wikipedia它今天不工作。我不知道你爲什麼要衝洗流。 –

+0

我使用memorystream的原因是因爲一些日文/中文網站使用Shift-JIS/Big5等,其中ascii代碼被識別,但亞洲字符不能被正確解釋。 –