В моем приложении я читаю реестр, чтобы получить все имена TimeZone. Он отлично работает с машиной ОС на английском языке.
Но для китайской родной ОС она показывает "????????".
Я использую 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 [] byte я получаю ненужные символы, поэтому, независимо от того, какую кодировку я использую для преобразования этого байтового массива в строку, я получаю только нежелательные символы. Может ли кто-нибудь предложить мне, какие изменения в этом методе заставят его работать нормально?
Я предполагаю, что вы имеете в виду взлом в этом ответе, который использует частный, недокументированный, специфичный для реализации API.
Этот код использует кодировку по умолчанию, чтобы вернуть возвращенные байты в символы:
return (valb != null ? new String(valb).trim() : null);
В Windows кодировка по умолчанию, скорее всего, будет устаревшей кодировкой - кодовой страницей ANSI.
Вам нужно будет вычислить кодировку данных и предоставить ее явно в конструкторе String(byte[],Charset)
или переключиться на документированный API - например, используя RegQueryValueExW с JNA.
Как отметил Осьминог в комментариях, также легко превратить символы в мусор, используя System.out
поскольку он также использует кодировки с потерями.