2011-03-15 91 views
4

我正在使用FileUpload服務器控件上載先前從MS Word保存(作爲網頁;過濾)的HTML文檔。字符集是windows-1252。 該文檔具有智能引號(捲曲)以及常規引號。它還具有一些空白區域(顯然),當深入查看除了正常TAB或SPACE以外的其他字符。FileUpload服務器控件和Unicode字符

在捕獲StreamReader中的文件內容時,這些特殊字符會被轉換爲問號。我假設它是因爲默認的encoidng是UTF-8而文件是Unicode。

我繼續使用Unicode編碼創建StreamReader,然後用正確的(我實際上在stackoverflow中找到的代碼)替換所有不需要的字符。這似乎工作....只是我不能將字符串轉換回UTF-8以顯示它在asp:文字。 代碼在那裏,它應該工作....但輸出(ConvertToASCII)是不可讀的。此外

protected void btnUpload_Click(object sender, EventArgs e) 
    { 
     StreamReader sreader; 
     if (uplSOWDoc.HasFile) 
     { 
      try 
      { 
       if (uplSOWDoc.PostedFile.ContentType == "text/html" || uplSOWDoc.PostedFile.ContentType == "text/plain") 
       { 
        sreader = new StreamReader(uplSOWDoc.FileContent, Encoding.Unicode); 
        string sowText = sreader.ReadToEnd(); 
        sowLiteral.Text = ConvertToASCII(sowText); 
        lblUploadResults.Text = "File loaded successfully."; 
       } 
       else 
        lblUploadResults.Text = "Upload failed. Just text or html files are allowed."; 
      } 
      catch(Exception ex) 
      { 
       lblUploadResults.Text = ex.Message; 
      } 
     } 
    } 

    private string ConvertToASCII(string source) 
    { 
     if (source.IndexOf('\u2013') > -1) source = source.Replace('\u2013', '-'); 
     if (source.IndexOf('\u2014') > -1) source = source.Replace('\u2014', '-'); 
     if (source.IndexOf('\u2015') > -1) source = source.Replace('\u2015', '-'); 
     if (source.IndexOf('\u2017') > -1) source = source.Replace('\u2017', '_'); 
     if (source.IndexOf('\u2018') > -1) source = source.Replace('\u2018', '\''); 
     if (source.IndexOf('\u2019') > -1) source = source.Replace('\u2019', '\''); 
     if (source.IndexOf('\u201a') > -1) source = source.Replace('\u201a', ','); 
     if (source.IndexOf('\u201b') > -1) source = source.Replace('\u201b', '\''); 
     if (source.IndexOf('\u201c') > -1) source = source.Replace('\u201c', '\"'); 
     if (source.IndexOf('\u201d') > -1) source = source.Replace('\u201d', '\"'); 
     if (source.IndexOf('\u201e') > -1) source = source.Replace('\u201e', '\"'); 
     if (source.IndexOf('\u2026') > -1) source = source.Replace("\u2026", "..."); 
     if (source.IndexOf('\u2032') > -1) source = source.Replace('\u2032', '\''); 
     if (source.IndexOf('\u2033') > -1) source = source.Replace('\u2033', '\"'); 


     byte[] sourceBytes = Encoding.Unicode.GetBytes(source); 
     byte[] targetBytes = Encoding.Convert(Encoding.Unicode, Encoding.ASCII, sourceBytes); 
     char[] asciiChars = new char[Encoding.ASCII.GetCharCount(targetBytes, 0, targetBytes.Length)]; 
     Encoding.ASCII.GetChars(targetBytes, 0, targetBytes.Length, asciiChars, 0); 

     string result = new string(asciiChars); 

     return result; 

    } 

,正如我以前說過,有一些更「透明」字,似乎相當於使Word文檔已編號壓痕,我不知道如何捕捉:

請看看下面他們的unicode價值取代他們....所以如果你有任何提示,請讓我知道。

非常感謝!

回答

5

根據StreamReader on MSDN

StreamReader對象試圖通過查看 的前三個字節流來檢測編碼。 它會自動識別UTF-8, 小端Unicode和大端 Unicode文本,如果文件以 開頭,則爲相應的字節順序標記。 否則,使用用戶提供的編碼 。

因此,如果您上傳的文件的字符集爲windows-1252,那麼你的行:

sreader = new StreamReader(uplSOWDoc.FileContent, Encoding.Unicode); 

是不正確,因爲文件的內容不採用Unicode編碼。相反,使用:

sreader = new StreamReader(uplSOWDoc.FileContent, 
        Encoding.GetEncoding("Windows-1252"), true); 

其中的final boolean parameter is to detect the BOM

+0

謝謝兄弟!!! ...做到了! – allendehl 2011-03-16 17:21:24

+0

不客氣。 – 2011-03-16 17:33:47

5
sreader = new StreamReader(uplSOWDoc.FileContent, Encoding.Unicode); 

恭喜,您是被「Encoding.Unicode」咬住的第一百萬編碼器。

沒有「Unicode編碼」這樣的東西。 Unicode是字符集,它有許多不同的編碼。

Encoding.Unicode實際上是特定的編碼UTF-16LE,其中字符被編碼爲UTF-16「編碼單元」,然後每個16位編碼單元以小端順序寫入字節。這是用於Windows NT的本地內存中Unicode字符串格式,但您幾乎不希望將其用於讀取或寫入文件。作爲一個2字節的單位編碼,它不是ASCII兼容的,並且它對於存儲或連線的效率並不高。

這些天來,UTF-8是一種更常見的用於Unicode文本的編碼。但是,微軟將UTF-16LE誤稱爲「Unicode」,繼續混淆並愚弄只想「支持Unicode」的用戶。由於Encoding.Unicode是一種非ASCII兼容編碼,試圖以ASCII超集編碼(例如UTF-8或Windows默認代碼頁,如1252西歐版)讀取文件會造成一切困難,而非只是非ASCII字符。

在這種情況下,你的編碼文件存儲在爲Windows代碼頁1252因此,與閱讀:

sreader= new StreamReader(uplSOWDoc.FileContent, Encoding.GetEncoding(1252)); 

我會離開它。不要試圖「轉換爲ASCII」。這些聰明的引號是非常好的字符,應該像任何其他Unicode字符一樣受到支持;如果您在顯示智能引號時遇到問題,那麼您可能也會損壞所有其他非ASCII字符。最好解決導致這種情況發生的問題,而不是僅僅爲了幾個常見情況而避免它。