Читайте символы Юникода из реестра в Java

1

В моем приложении я читаю реестр, чтобы получить все имена 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 я получаю ненужные символы, поэтому, независимо от того, какую кодировку я использую для преобразования этого байтового массива в строку, я получаю только нежелательные символы. Может ли кто-нибудь предложить мне, какие изменения в этом методе заставят его работать нормально?

  • 0
    проверьте это один stackoverflow.com/questions/9309899/converting-byte-to-string
  • 1
    Где видны знаки вопроса? В консоли?
Показать ещё 1 комментарий
Теги:

1 ответ

1

Я предполагаю, что вы имеете в виду взлом в этом ответе, который использует частный, недокументированный, специфичный для реализации API.

Этот код использует кодировку по умолчанию, чтобы вернуть возвращенные байты в символы:

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

В Windows кодировка по умолчанию, скорее всего, будет устаревшей кодировкой - кодовой страницей ANSI.

Вам нужно будет вычислить кодировку данных и предоставить ее явно в конструкторе String(byte[],Charset) или переключиться на документированный API - например, используя RegQueryValueExW с JNA.

Как отметил Осьминог в комментариях, также легко превратить символы в мусор, используя System.out поскольку он также использует кодировки с потерями.

  • 0
    Но я проверил байты, которые я получаю в valb []. И эти байты сами содержат "??????". Поэтому, какую бы кодировку мы не использовали, это не поможет ..
  • 0
    Ах хорошо. Когда Java Preferences API сохраняет значения Unicode в реестре Windows, он выполняет собственный экранирование Unicode - он никогда не предназначался для общего типа чтения реестра. Взлом WinRegistry.java нарушает внутреннюю часть этого API. Это может объяснить, почему данные массива повреждены в некоторых локалях. Я бы посмотрел на использование нативного кода.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню