2014-04-01 46 views
1

在我的應用程序中,我正在讀取註冊表以獲取所有TimeZone名稱。 它與原生英文OS機器正常工作。從java註冊表中讀取unicode字符

但是對於中國本土的操作系統,它顯示「????????」。

我正在使用WinRegistry.java,通用文件可用於讀取註冊表中的Java。

下面是從註冊表中讀取字節的方法,但該字節僅包含垃圾字符。

private static String readString(Preferences root, int hkey, String key, String value) 
    throws IllegalArgumentException, IllegalAccessException, 
    InvocationTargetException 
    { 
    int[] handles = (int[]) regOpenKey.invoke(root, new Object[] { 
     new Integer(hkey), toCstr(key), new Integer(KEY_READ) }); 
    if (handles[1] != REG_SUCCESS) { 
     return null; 
    } 
    byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] { 
     new Integer(handles[0]), toCstr(value) }); 
    regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) }); 
    return (valb != null ? new String(valb).trim() : null); 
    } 

在值Valb []字節數組,我收到垃圾字符,所以我使用任何編碼到字節數組字符串轉換,我只得到垃圾字符。 任何人都可以建議我,這種方法的改變會使它工作正常嗎?

+0

檢查這一個http://stackoverflow.com/questions/9309899/converting-byte-to-string –

+1

哪裏看到問號?在控制檯中? – Keerthivasan

+0

我在回顧字符串,並將其放入下拉列表中。 在下拉列表中,我可以看到問號。 – JayRaj

回答

1

我假設你的意思是the hack in this answer,它使用私有的,未公開的,實現特定的API。

該代碼使用default encoding打開返回的字節到字符:

return (valb != null ? new String(valb).trim() : null); 

在Windows中,默認的編碼可能是傳統的編碼 - 一個"ANSI" code page

您需要計算出String(byte[],Charset)構造函數中的數據編碼和provide it explicitly,或切換到記錄的API - 例如,使用RegQueryValueExWJNA

正如Octopus在評論中指出的那樣,使用System.out也很容易將字符變成垃圾,因爲它也使用有損遺留編碼。

+0

但我已經檢查了我在valb []中獲得的字節。那個字節它自己包含「??????」。所以無論我們使用什麼編碼都不會幫助.. – JayRaj

+0

啊,好的。當Java的Preferences API在Windows註冊表中存儲Unicode值時,它會自行進行Unicode轉義 - 它從來沒有打算成爲通用的註冊表閱讀器類型。 WinRegistry.java的破解濫用了這個API的內部。這可以解釋爲什麼在某些語言環境下數組數據已損壞。我會看看使用本機代碼。 – McDowell