Консоль Java, UTF-8 и Windows

Мы стараемся использовать Java и UTF-8 в Windows. Приложение записывает журналы на консоль, и мы хотели бы использовать для журналов UTF-8, поскольку наше приложение имеет интернационализированные журналы.

Можно настроить JVM так, чтобы он генерировал UTF-8, используя -Dfile.encoding=UTF-8 в качестве аргументов JVM. Он работает нормально, но вывод на консоль Windows искажен.

Затем мы можем установить кодовую страницу консоли на 65001 (chcp 65001), но в этом случае файлы .bat не работают. Это означает, что когда мы пытаемся запустить наше приложение через наш скрипт (с именем start.bat), абсолютно ничего не происходит. Команда simple возвращает:

C:\Application> chcp 65001
Activated code page: 65001
C:\Application> start.bat

C:\Application>

Но без chcp 65001 проблем нет, и приложение можно запустить.

Есть намеки на это?

Какая кодировка текста у файла start.bat?

johnstok 05.11.2008 17:40
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
14
1
20 800
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы пробовали PowerShell, а не старый cmd.exe.

PowerShell по-прежнему использует ту же консоль, поэтому она такая же старая и дрянная, как cmd.exe.

Trejkaz 28.05.2013 07:22
Ответ принят как подходящий

Попробуйте chcp 65001 && start.bat

Команда chcp изменяет кодовую страницу, а 65001 - это идентификатор кодовой страницы Win32 для UTF-8 в Windows 7 и более поздних версиях. Кодовая страница или кодировка символов указывает, как преобразовать кодовую точку Unicode в последовательность байтов или обратно.

Это должно использоваться вместе с -Dfile.encoding = UTF-8 для правильной работы.

Axel Fontaine 29.04.2014 18:11

@AxelFontaine Я пробовал использовать -Dfile.encoding = UTF-8, но при использовании символа квадратного корня последние 2 числа после символа повторялись. Например, вместо √125 на выходе будет √12525.

Cj1m 11.10.2014 15:21

У нас были похожие проблемы в Linux. Наш код был в ISO-8859-1 (в основном совместим с cp-1252), но консоль была в UTF-8, поэтому код не компилировался. Простое изменение консоли на ISO-8859-1 приведет к поломке сценария сборки в UTF-8. Мы нашли несколько вариантов:
1- определить стандартную кодировку и придерживаться ее. Это был наш выбор. Мы решили сохранить все в ISO-8859-1, изменив сценарии сборки. 2- Установка кодировки перед запуском любой задачи, даже внутри скриптов сборки. Какой-то код, как сказал Эриксон. В линуксе было примерно так:

lang=pt_BR.ISO-8859-1 /usr/local/xxxx

Мое затмение все еще такое. Оба работают хорошо.

Похоже на шаг назад, чтобы придерживаться (и изменять) ISO-8859-1 вместо UTF-8. Но, вероятно, у Вас были свои причины.

KarolDepka 20.02.2010 18:35

Windows не поддерживает кодовую страницу 65001: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/chcp.mspx?mfr=true

Он начал поддерживать его с Windows 7.

erickson 14.08.2020 20:01

Java в Windows по умолчанию НЕ поддерживает вывод в формате Unicode. Я написал обходной метод, вызвав собственный API с библиотекой JNA. Метод вызовет WriteConsoleW для вывода в Юникоде на консоль.

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;

/** For unicode output on windows platform
 * @author Sandy_Yin
 * 
 */
public class Console {
    private static Kernel32 INSTANCE = null;

    public interface Kernel32 extends StdCallLibrary {
        public Pointer GetStdHandle(int nStdHandle);

        public boolean WriteConsoleW(Pointer hConsoleOutput, char[] lpBuffer,
                int nNumberOfCharsToWrite,
                IntByReference lpNumberOfCharsWritten, Pointer lpReserved);
    }

    static {
        String os = System.getProperty("os.name").toLowerCase();
        if (os.startsWith("win")) {
            INSTANCE = (Kernel32) Native
                    .loadLibrary("kernel32", Kernel32.class);
        }
    }

    public static void println(String message) {
        boolean successful = false;
        if (INSTANCE != null) {
            Pointer handle = INSTANCE.GetStdHandle(-11);
            char[] buffer = message.toCharArray();
            IntByReference lpNumberOfCharsWritten = new IntByReference();
            successful = INSTANCE.WriteConsoleW(handle, buffer, buffer.length,
                    lpNumberOfCharsWritten, null);
            if (successful){
                System.out.println();
            }
        }
        if (!successful) {
            System.out.println(message);
        }
    }
}

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