Java не печатает персидский точно в командной строке Windows

Вот мой код:

class Hello{
    public static void main(String[] arg)throws Exception{
        System.out.println("Hello");
        String str = "سلام";
            System.out.println(new String(str.getBytes("UTF-8")));
    }
}

Компиляция как: javac -encoding UTF8 Hello.java Результат:

C:\Users\Windows\Desktop>java Hello
Hello
ط³ظ„ط§ظ…

chcp показывает: Active code page: 65001

Как я могу отобразить это точно?

С наилучшими пожеланиями

Посмотрите, поможет ли это.

Federico klez Culloca 11.08.2023 12:32

Я не могу воспроизвести это, я попробовал ваш код, и он может отображаться правильно

时间只会一直走 11.08.2023 12:33

Почему вы берете строку, преобразуете ее в байты UTF-8 и обратно в строку (возможно, в другой кодировке символов)? Почему бы не просто System.out.println(str);?

Andy Turner 11.08.2023 12:38

@AndyTurner Когда я печатаю только str, то компилируется, но ничего не отображается

user987376746090 11.08.2023 12:41

@时间只会一直走 Have you please tried in windows command line?

user987376746090 11.08.2023 12:42
new String(str.getBytes("UTF-8")) возьмет вашу строку, преобразует ее в байты, используя UTF-8, а затем преобразует ее обратно в строку, используя либо UTF-8 (на современных JVM, я думаю, jdk17+), либо используя локальную кодировку вашей платформы. Если это UTF-8, это бессмысленно и производит то же самое, что и просто str. Если это не UTF-8, вы проигрываете игру, и ваша строка становится непоправимо абракадаброй. Что бы ни происходило, не делайте эту часть. Затем ваша строка преобразуется обратно в byte[] в третий раз при отправке на стандартный вывод. Затем ваша ОС преобразует его обратно в строку и печатает.
rzwitserloot 11.08.2023 13:13

Просто напечатайте str. Если это ничего не печатает, идите отлаживать его. Что печатает System.out.println(System.getProperty("native.encoding"));?

rzwitserloot 11.08.2023 13:15

@rzwitserloot печатает null

user987376746090 11.08.2023 13:36

@user, значит, вы используете старый JDK. Хорошо, старая версия это System.out.println(Charset.defaultCharset()).

rzwitserloot 11.08.2023 18:04

Вывод @rzwitserloot: windows-1256

user987376746090 11.08.2023 18:13

Я не думаю, что это вообще может обрабатывать персидские символы. Никакой Java-код не мог бы заставить его работать.

rzwitserloot 11.08.2023 18:57

@rzwitserloot, тогда что мне делать? Могу ли я обновить свой jdk до более новой версии или что-то еще?

user987376746090 11.08.2023 19:30

Перед вами случай моджибаке (пример на Python для его универсальной понятности): "سلام".encode('utf-8').decode('cp1256') возвращает 'ط³ظ„ط§ظ…'. Я предполагаю, что System.out.println("سلام"); или System.out.println(str); должны работать вместо System.out.println(new String(str.getBytes("UTF-8")));

JosefZ 11.08.2023 21:39

@JosefZ Я пытался System.out.println("سلام");, но отображается странный символ

user987376746090 12.08.2023 08:09
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
14
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш код в порядке, но у вас есть две проблемы:

  • Вы используете шрифт в окне командной строки, который не поддерживает должным образом символы фарси.
  • На фарси пишут справа налево, но окно командной строки отображает текст слева направо, поэтому, даже если вы используете подходящий шрифт, текст на фарси будет отображаться в обратном порядке.

Используя ваш образец приложения, вот как выходные данные были отображены в моем окне командной строки с использованием шрифта Courier New, который поддерживает символы фарси:

Обратите внимание, что символы отрисовывались правильно, но в обратном порядке.

Может быть простой обходной путь, чтобы заставить символы правильно отображать текст справа налево в окне командной строки, но в любом случае лучший альтернативный подход — вместо этого использовать реализацию командной строки, предоставляемую утилитой терминала Microsoft.

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

Примечания:

  • Моя среда — Windows 10 с использованием локали США с кодовой страницей по умолчанию 65001. Я тестировал с использованием JDK 20, но любая версия JDK должна подойти.
  • Если вам не нужно использовать традиционное окно командной строки из соображений совместимости, рассмотрите возможность использования вместо этого реализации командной строки, предоставляемой Терминалом. Все виды проблем с рендерингом текста просто исчезают, потому что были устранены некоторые давние ошибки / ограничения с традиционным окном командной строки.
  • Если вы не знакомы с Терминалом, это обзор Microsoft описание:

Windows Terminal — это современное хост-приложение для уже любимых вами оболочек командной строки, таких как Command Prompt, PowerShell и bash. (через подсистему Windows для Linux (WSL)). К его основным особенностям относятся несколько вкладок, панелей, поддержка символов Unicode и UTF-8, графический процессор ускоренный движок рендеринга текста и возможность создавать собственные темы и настраивайте текст, цвета, фон и ярлыки.

Другие вопросы по теме