2009-10-08 59 views
0

當我使用Notepad ++檢查文件時,它使用ANSI編碼。我在這裏做錯了什麼?即使將編碼設置爲UTF-8,文件也不會保存爲UTF-8編碼

OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), "UTF8"); 
try 
     {   
      out.write(text); 
      out.flush(); 
     } finally 
     { 
      out.close(); 
     } 

UPDATE:

這是現在解決了,原因JBoss的不理解我的XML並沒有編碼,但它被命名我的XML。感謝所有的幫助,即使真的沒有任何問題...

+0

請問您的文字有任何非ASCII字符?記事本只是對數據進行啓發式檢查)。 –

+0

在應用程序的XML和我的測試文件中它的唯一字母 – newbie

+0

您的評論如下表明,這不是導致問題的實際代碼。請用實際的代碼,JBoss給你的消息和XML文件的樣本進行編輯。 – kdgregory

回答

2

UTF-8的設計是,在通常情況下,從ANSI而難以區分。因此,當您將文本寫入文件並使用UTF-8編碼文本時,通常情況下,打開文件的其他人看起來像ANSI。

  • 對於所有ASCII字符,UTF-8都是1字節,就像ANSI一樣。
  • 對於ASCII字符,UTF-8具有與ANSI相同的所有字節。
  • UTF-8沒有任何特殊的標題字符,就像ANSI沒有。

它只有當你開始進入非ASCII代碼點,事情開始看起來不同。

但在通常情況下,字節爲字節,ANSI和UTF-8是相同的。

+2

這不是真的,ANSI和UTF-8通常是相同的。只有使用ASCII字符時,ANSI和UTF-8才相同(代碼介於0-127之間)。非ASCII字符(如「áéíóúÁÉÓÓñÑÑ」)在UTF-8中有多字節編碼(這些特定集合有2個字節)。在ANSI中,每個字符都用1個字節編碼。 ANSI和UTF-8何時相同?當不使用「陌生」字符時,通過「陌生」理解英語中找不到的任何字符(字母/標點符號/重音符號)。 –

+0

正是這一點:毫無疑問,「新手」在他的輸入中有很多非ASCII字符,暗示他錯誤地將「字母表」用作「字母表元素」,這在印度的英語人士中很常見, 尤其是。他使用「ANSI」來表示他的文件被解釋爲使用一些8位編碼(可能是Windows-1252),並以無意義的重音字符序列出現(「它的唯一字母」)。 –

+0

「常見」是字節00到7F。當文本中的所有代碼點都可以用UTF-8在00-7F範圍內的單個字節中表示時,那麼UTF-8編碼的文本是ANSI。這包括大多數英語不帶重音的文本。 – yfeldblum

0

IANA註冊類型是「UTF-8」,而不是「UTF8」。但是,Java應該爲無效編碼引發異常,所以這可能不是問題。

我懷疑記事本是問題所在。使用hexdump程序檢查文本,你應該看到它正確編碼。

+0

我創建了應該用UTF-8編碼的XML文件,但是jboss不能使用該文件,但是當我用Notepad ++手動將編碼更改爲UTF-8時,那麼jboss會理解應該使用UTF-8的XML – newbie

1

如果沒有BOM(並且Java不輸出一個用於UTF8,它甚至不能識別它),只要只使用ASCII範圍內的字符,則ANSI和UTF8編碼中的文本是相同的。因此Notepad ++無法檢測到任何差異。

(而且似乎是一個issue with UTF8 in Java反正...)

+1

This isn真的不是問題。在很多情況下,您不希望UTF-8數據以BOM作爲前綴。 Unicode BOM常見問題解答:http://unicode.org/faq/utf_bom.html#bom10 – McDowell

+1

這是自動(而且非常可靠地)檢測UTF-8和ASCII或ANSI字符集之間差異的可能性之一。你如何從別的方面瞭解UTF-8? – Lucero

+0

我並不質疑您可以(或者是否應該)在任何情況下使用BOM;你是對的,這當然是一種可能性。然而,太多的情況下,BOM會破壞數據(例如,unix腳本;附加到文件)或者完全不必要(例如數據庫記錄),以便用U + FEFF爲每個UTF-8編碼流加上前綴。我不會將此描述爲Java的一個問題,因爲開發人員無法理解如何使用編碼以及如何/何時使用物料清單等問題。 – McDowell

2

如果要創建一個XML文件(因爲您的評論暗示),我會強烈建議您使用XML庫來輸出這個寫入正確的XML編碼頭。否則,你的字符編碼將不符合XML標準,其他工具(比如你的JBoss實例)會正確地投訴。

// Prepare the DOM document for writing 
    Source source = new DOMSource(doc); 

    // Prepare the output file 
    File file = new File(filename); 
    Result result = new StreamResult(file); 

    // Write the DOM document to the file 
    Transformer xformer = TransformerFactory.newInstance().newTransformer(); 
    xformer.transform(source, result); 
2

沒有明文這樣的東西。問題在於應用程序正在解碼字符數據,而沒有告訴它它使用了哪種編碼。

儘管許多Microsoft應用程序依賴於存在Byte Order Mark來表示Unicode文件,但這絕不是標準。 The Unicode BOM FAQ says more.

您可以通過在流的開始處寫入字符'\uFEFF'來向輸出添加物料清單。 More info here。對於依賴物料清單的應用來說,這應該足夠了。

0

您是否嘗試在文件的開頭寫入BOM? BOM是唯一可以告訴編輯器該文件是UTF-8的東西。否則,UTF-8文件可能看起來像Latin-1或擴展的ANSI。

你可以像這樣做,

public final static byte[] UTF8_BOM = {(byte)0xEF, (byte)0xBB, (byte)0xBF}; 
... 
OutputStream os = new FileOutputStream(file); 
os.write(UTF8_BOM); 
os.flush(); 
OutputStreamWriter out = new OutputStreamWriter(os, "UTF8"); 
try 
    {      
      out.write(text); 
      out.flush(); 
    } finally 
    { 
      out.close(); 
    }