2009-01-19 19 views
4

我有一個Java程序在外部進程中運行msinfo32.exe(系統信息),然後讀取由msinfo32.exe生成的文件內容。當Java程序將文件內容加載到String中時,String字符不可讀。爲了使字符串可讀,我必須使用String(byte [] bytes,String charsetName)創建String,並將charsetName設置爲UTF-16。但是,當在Windows2003的一個實例上運行時,只有UTF-16LE(小端)會生成可打印的字符串。Java字符集和Windows

如何提前知道要使用哪種字符編碼?

此外,任何關於這個主題的背景信息將不勝感激。

回答

1

你不能真正知道使用了什麼字符編碼(除非你創建了創建你正在處理的輸出的工具)。您可以嘗試檢測預定義的編碼列表,並選擇不會導致任何解碼錯誤但取決於可能匹配很多不同編碼的輸入的編碼。

0

如果您事先不知道字符編碼,並且這在不同的平臺中是不同的,那麼您需要以某種方式分析字節數組以嘗試猜測它。有一些檢測算法可用,但它可能對您的應用程序是一個矯枉過正。

你可以調整你的應用程序來產生已知的輸出嗎?沒有必要成爲一個完整的隊伍,只有第一個角色會做。如果是的話,那麼你可以比較產生的字節數組和預期的各種編碼並進行檢測。對於簡單字符串,UTF8,UTF-16大小端的字節數組將是不同的事件。

2

您可以嘗試使用庫來猜測編碼,例如我曾經使用過this solution

+1

鏈接似乎已經死了... – assylias 2012-11-12 17:36:37

5

某些Microsoft應用程序使用byte-order mark來指示Unicode文件及其字節順序。我可以在我的Windows XP機器上看到導出的.NFO文件以0xFFFE開頭,因此它是小端。

FF FE 3C 00 3F 00 78 00 6D 00 6C 00 20 00 76 00   __<_?_x_m_l_ _v_ 
65 00 72 00 73 00 69 00 6F 00 6E 00 3D 00 22 00   e_r_s_i_o_n_=_"_ 
31 00 2E 00 30 00 22 00 3F 00 3E 00 0D 00 0A 00   1_._0_"_?_>_____ 
3C 00 4D 00 73 00 49 00 6E 00 66 00 6F 00 3E 00   <_M_s_I_n_f_o_>_ 
0D 00 0A 00 3C 00 4D 00 65 00 74 00 61 00 64 00   ____<_M_e_t_a_d_ 

另外,我建議你改用Reader實現,而不是解碼文件String構造;這有助於避免在讀取一半字符時出現問題,因爲它被截斷,因爲它位於字節數組的末尾。

0

它應該工作的方式是,如果有人給你一個文件並說它是UTF-16,他們希望你檢查前兩個字節(BOM),以確定它是大端還是小端。但是如果他們告訴你編碼是UTF-16LE,這意味着沒有BOM;你不需要它,因爲他們已經告訴你字節順序是小端的。 Java精確地遵循這些規則,因爲沒有其他人會這樣做,所以這是一個真正的實體。

現代Windows操作系統的本地字符編碼是UTF-16,小端。不幸的是,單個程序在字節順序標記方面似乎並不一致。而且你不能一直使用UTF-16LE,因爲如果BOM 在那裏是,它將作爲垃圾字符傳遞。提前知道是否使用UTF-16或UTF-16LE的唯一方法是檢查前兩個字節,正如McDowell所述。