Java,UTF-8和Windows控制台

Java,UTF-8和Windows控制台

Java, UTF-8, and Windows console

我们尝试在Windows上使用Java和UTF-8。 该应用程序在控制台上写入日志,我们希望对日志使用UTF-8,因为我们的应用程序具有国际化的日志。

可以配置JVM,以便使用-Dfile.encoding=UTF-8作为JVM的参数来生成UTF-8。 它工作正常,但Windows控制台上的输出出现乱码。

然后,我们可以将控制台的代码页设置为65001(chcp 65001),但是在这种情况下,.bat文件不起作用。 这意味着当我们尝试通过脚本(名为start.bat)启动应用程序时,绝对没有任何反应。 命令简单返回:

1
2
3
4
5
C:\Application> chcp 65001
Activated code page: 65001
C:\Application> start.bat

C:\Application>

但是没有chcp 65001,就没有问题,并且可以启动该应用程序。

有什么暗示吗?


Windows上的Java默认情况下不支持Unicode输出。我通过使用JNA库调用Native API编写了一种解决方法,该方法将调用WriteConsoleW在控制台上输出unicode。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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);
        }
    }
}

尝试chcp 65001 && start.bat


Windows不支持65001代码页:http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/chcp.mspx?mfr=true


我们在Linux中也遇到了类似的问题。我们的代码在ISO-8859-1中(大多数与cp-1252兼容),但是控制台是UTF-8,因此代码无法编译。只需将控制台更改为ISO-8859-1,就可以破坏UTF-8中的构建脚本。我们找到了两个选择:
1-定义一些标准的编码和坚持。那是我们的选择。我们选择将所有内容保留在ISO-8859-1中,并修改构建脚本。
2-在开始任何任务之前设置编码,即使在构建脚本中也是如此。像埃里克森所说的一些代码。在Linux中就像:

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

我的日食还是这样。两者都运作良好。


您是否尝试过PowerShell,而不是旧的cmd.exe。


推荐阅读