2012-09-27 16 views
3

我試圖將所有Windows特殊字符轉換爲它們的Unicode等效項。我們有一個Flex應用程序,用戶保存一些Rich Text,然後通過Java Emailer通過電子郵件發送給他們的收件人。然而,我們仍然在運行Word中的特殊字符,這些字符只是在電子郵件中顯示爲?將Windows-1252轉換爲Java中的UTF-16

到目前爲止,我已經試過

private String replaceWordChars(String text_in) { 
    String s = text_in; 

    // smart single quotes and apostrophe 
    s = s.replaceAll("[\\u2018|\\u2019|\\u201A]", "\'"); 
    // smart double quotes 
    s = s.replaceAll("[\\u201C|\\u201D|\\u201E]", "\""); 
    // ellipsis 
    s = s.replaceAll("\\u2026", "..."); 
    // dashes 
    s = s.replaceAll("[\\u2013|\\u2014]", "-"); 
    // circumflex 
    s = s.replaceAll("\\u02C6", "^"); 
    // open angle bracket 
    s = s.replaceAll("\\u2039", "<"); 
    // close angle bracket 
    s = s.replaceAll("\\u203A", ">"); 
    // spaces 
    s = s.replaceAll("[\\u02DC|\\u00A0]", " "); 

    return s; 

其中一期工程,但我不想編碼所有的Windows-1252字符交給他們相當於UTF-16(假設這是默認的Java字符集是什麼)

但是,我們的用戶不斷從Microsoft Word中找到Java無法處理的更多字符。所以,我找啊找,找到了這個例子

private String replaceWordChars(String text_in) { 
    String s = text_in; 
    try { 
     byte[] b = s.getBytes("Cp1252"); 
     byte[] encoded = new String(b, "Cp1252").getBytes("UTF-16"); 
     s = new String(encoded, "UTF-16"); 


    } catch (UnsupportedEncodingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return s; 

但是,當我看到在Eclipse調試器中編碼發生,沒有什麼變化。

必須有一個簡單的解決方案來處理微軟可愛的Java編碼。

有什麼想法?

+1

在第一種情況下,你只是用ASCII字符替換非ASCII字符。你根本沒有改變*編碼*。在第二段代碼中,除了將所有無法由Cp1252處理的字符轉換爲「? –

+0

Ok @JonSkeet關於用它們的ASCII等價物替換所有非ASCII字符的想法嗎? – idonaldson

+0

@CodingGuy並非所有的非ASCII字符都有相應的ascii ... ASCII字符少於128個字符,並且有超過100,000個Unicode字符。你需要弄清楚如何正確發送電子郵件。發送的電子郵件是什麼編碼?它應該是UTF-8,然後你不必刪除非ASCII字符。 – bames53

回答

4

final Charset windowsCharset = Charset.forName("windows-1252"); 
final Charset utfCharset = Charset.forName("UTF-16"); 
final CharBuffer windowsEncoded = windowsCharset.decode(ByteBuffer.wrap(new byte[] {(byte) 0x91})); 
final byte[] utfEncoded = utfCharset.encode(windowsEncoded).array(); 
System.out.println(new String(utfEncoded, utfCharset.displayName())); 
2

使用以下步驟:

  1. 使用源文件的編碼(WINDOWS 1252)
  2. 使用目標文件的編碼創建OutputStreamWriter創建InputStreamReader(UTF-16)
  3. 複製信息從讀者讀到作者。您可以使用BufferedReaderBufferedWriter逐行寫入內容。

所以,你的代碼可能是這樣的:

public void reencode(InputStream source, OutputStream dest, 
     String sourceEncoding, String destEncoding) 
     throws IOException { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(source, sourceEncoding)); 
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(dest, destEncoding)); 
    String in; 
    while ((in = reader.readLine()) != null) { 
     writer.write(in); 
     writer.newLine(); 
    } 
} 

這當然不包括的try/catch的東西,將其委託給調用者。

如果您只是想將內容作爲各種字符串取得,您可以用代替writer並返回其toString值。那麼你並不需要一個目標流或編碼,只需要一個地方傾倒字符:你可以嘗試使用java.nio.charset.Charset

public String decode(InputStream source, String sourceEncoding) 
     throws IOException { 
    BufferedReader reader = new BufferedReader(new InputStreamReader(source, sourceEncoding)); 
    StringWriter writer = new StringWriter(); 
    String in; 
    while ((in = reader.readLine()) != null) { 
     writer.write(in); 
     writer.write('\n'); // Java newline should be fine, test this just in case 
    } 
    return writer.toString(); 
} 
+0

爲什麼downvote?沒有代碼?現在寫。請先評論,請稍後再投票。 – Brian

+0

步驟1不起作用。這來自網絡上的Flex RIA。用戶很可能會用文字輸入他們看起來不錯的電子郵件,然後複製粘貼到我們的應用程序中併發送電子郵件。我會試試Streams,看看會發生什麼。 – idonaldson

+0

我剛推薦它。我正在寫的代碼實際上只是使用流。一切順利。我會將其包含在我的編輯中。 – Brian

1

什麼似乎工作至今的一切我已經測試是:

private String replaceWordChars(String text_in) { 
    String s = text_in; 

    final Charset windowsCharset = Charset.forName("windows-1252"); 
    final Charset utfCharset  = Charset.forName("UTF-16"); 

    byte[] incomingBytes = s.getBytes(); 
    final CharBuffer windowsEncoded = windowsCharset.decode(ByteBuffer.wrap(incomingBytes)); 

    final byte[] utfEncoded   = utfCharset.encode(windowsEncoded).array(); 
    s = new String(utfEncoded); 

    return s; 
}