Как указать значение Java file.encoding в соответствии с базовой кодовой страницей Windows? - PullRequest
7 голосов
/ 26 августа 2009

У меня есть приложение Java, которое получает данные через сокет, используя InputStreamReader. Он сообщает "Cp1252" из метода getEncoding:

/* java.net. */ Socket Sock = ...;
InputStreamReader is = new InputStreamReader(Sock.getInputStream());
System.out.println("Character encoding = " + is.getEncoding());
// Prints "Character encoding = Cp1252"

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

C:\>chcp
Active code page: 850

Приложение может получить байт 0x81, который в кодовой странице 850 представляет символ ü. Программа интерпретирует этот байт с помощью кодовой страницы 1252, которая не определяет какой-либо символ при этом значении, поэтому вместо этого я получаю знак вопроса.

Мне удалось обойти эту проблему для одного клиента, который использовал кодовую страницу 850, добавив еще один параметр командной строки в командный файл, запускающий приложение:

java.exe <b>-Dfile.encoding=Cp850</b> ...

Но не все мои клиенты, конечно, используют кодовую страницу 850. Как я могу заставить Java использовать кодовую страницу, которая совместима с базовой системой Windows? Я бы предпочел что-то, что я мог бы просто поместить в командный файл, оставив нетронутым код Java:

ENC=...
java.exe -Dfile.encoding=%ENC% ...

Ответы [ 4 ]

6 голосов
/ 27 августа 2009

Кодировка по умолчанию, используемая cmd.exe, равна Cp850 (или любой «OEM» CP, встроенный в ОС); системная кодировка - Cp1252 (или любой другой «ANSI» CP, свойственный ОС). Горы подробности здесь . Один из способов обнаружить кодировку консоли - сделать это с помощью собственного кода (см. GetConsoleOutputCP для текущей кодировки консоли; см. GetACP для кодировки по умолчанию "ANSI"; и т.д. .).

Изменение кодировки с помощью переключателя -D повлияет на все ваши механизмы кодирования по умолчанию, включая перенаправленный stdout / stdin / stderr. Это не идеальное решение.

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

'file:  setacp.vbs
'usage: cscript /Nologo setacp.vbs
Set objShell = CreateObject("WScript.Shell")
'replace ACP (ANSI) with OEMCP for default console CP
cp = objShell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001" &_
                              "\Control\Nls\CodePage\ACP")
WScript.Echo "Switching console code page to " & cp
objShell.Exec "chcp.com " & cp

(Это мой первый сценарий WSH, поэтому он может быть ошибочным - я не знаком с разрешениями на чтение из реестра.)

Использование шрифта TrueType является еще одним требованием для использования ANSI / Unicode с cmd.exe. Я собираюсь посмотреть на программный переход на лучший шрифт, когда позволит время.

5 голосов
/ 26 августа 2009

Что касается фрагмента кода, правильный ответ - использовать соответствующий конструктор для InputStreamReader, который выполняет правильное преобразование кода. Таким образом, не имеет значения, какая кодировка используется по умолчанию в системе, вы знаете, что получаете правильную кодировку, соответствующую тому, что вы получаете в сокете.

Тогда вы можете указать кодировку при записи файлов, если вам нужно, вместо того, чтобы полагаться на кодировку системы, но, конечно, когда они открывают файлы в этой системе, у них могут быть проблемы, но современные системы Windows поддерживают UTF-8 , так что вы можете записать файл в UTF-8, если вам нужно (внутренне Java представляет все строки как 16-битный Unicode).

Я бы подумал, что это «правильное» решение в целом, которое было бы наиболее совместимым с наибольшим диапазоном базовых систем.

4 голосов
/ 27 августа 2009

Если значение кодовой страницы, возвращаемое командой chcp, вернет нужное вам значение, вы можете использовать следующую команду для получения кодовой страницы

C:\>for /F "Tokens=4" %I in ('chcp') Do Set CodePage=%I

Устанавливает для переменной CodePage значение кодовой страницы, возвращаемое из chcp

C:\>echo %CodePage%
437

Вы можете использовать это значение в вашем bat-файле, добавив к нему префикс Cp

C:\>echo Cp%CodePage%
Cp437

Если вы поместите это в bat-файл, значения% I в первой команде нужно будет заменить на %% I

4 голосов
/ 27 августа 2009

В Windows есть дополнительная сложность, связанная с наличием двух активных кодовых страниц. В вашем примере и 1252, и 850 верны, но они зависят от способа запуска программы. Для приложений с графическим интерфейсом Windows будет использовать кодовую страницу ANSI, которая для западноевропейских языков обычно будет 1252. Тем не менее, командная строка сообщит кодовую страницу OEM, которая составляет 850 для тех же локалей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...