Java、UTF-8 和 Windows 控制台
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/54952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java, UTF-8, and Windows console
提问by tofcoder
We try to use Java and UTF-8 on Windows. The application writes logs on the console, and we would like to use UTF-8 for the logs as our application has internationalized logs.
我们尝试在 Windows 上使用 Java 和 UTF-8。应用程序在控制台上写入日志,我们希望对日志使用 UTF-8,因为我们的应用程序具有国际化的日志。
It is possible to configure the JVM so it generates UTF-8, using -Dfile.encoding=UTF-8
as arguments to the JVM. It works fine, but the output on a Windows console is garbled.
可以配置 JVM,使其生成 UTF-8,-Dfile.encoding=UTF-8
用作 JVM 的参数。它工作正常,但 Windows 控制台上的输出是乱码。
Then, we can set the code page of the console to 65001 (chcp 65001
), but in this case, the .bat
files do not work. This means that when we try to launch our application through our script (named start.bat), absolutely nothing happens. The command simple returns:
然后,我们可以将控制台的代码页设置为 65001 ( chcp 65001
),但在这种情况下,.bat
文件不起作用。这意味着当我们尝试通过我们的脚本(名为 start.bat)启动我们的应用程序时,绝对没有任何反应。命令简单返回:
C:\Application> chcp 65001
Activated code page: 65001
C:\Application> start.bat
C:\Application>
But without chcp 65001
, there is no problem, and the application can be launched.
但是没有chcp 65001
,没有问题,并且可以启动应用程序。
Any hints about that?
任何提示?
采纳答案by erickson
Try chcp 65001 && start.bat
尝试 chcp 65001 && start.bat
回答by sblundy
Have you tried PowerShellrather than old cmd.exe.
您是否尝试过PowerShell而不是旧的 cmd.exe。
回答by Renato Soffiatto
We had some similar problems in Linux. Our code was in ISO-8859-1 (mostly cp-1252 compatible) but the console was UTF-8, making the code to not compile. Simply changing the console to ISO-8859-1 would make the build script, in UTF-8, to break. We found a couple of choices:
1- define some standard encoding and sticky to it. That was our choice. We choose to keep all in ISO-8859-1, modifying the build scripts.
2- Setting the encoding before starting any task, even inside the build scripts. Some code like the erickson said. In Linux was like :
我们在 Linux 中遇到了一些类似的问题。我们的代码是 ISO-8859-1(主要是 cp-1252 兼容),但控制台是 UTF-8,使代码无法编译。简单地将控制台更改为 ISO-8859-1 会使 UTF-8 格式的构建脚本中断。我们找到了几个选择:
1- 定义一些标准编码并坚持使用它。那是我们的选择。我们选择将所有内容保留在 ISO-8859-1 中,修改构建脚本。
2- 在开始任何任务之前设置编码,甚至在构建脚本中。像埃里克森所说的一些代码。在 Linux 中是这样的:
lang=pt_BR.ISO-8859-1 /usr/local/xxxx
My eclipse is still like this. Both do work well.
我的日食还是这样。两者都运行良好。
回答by Roger F. Gay
Windows doesn't support the 65001 code page: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/chcp.mspx?mfr=true
Windows 不支持 65001 代码页:http: //www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/chcp.mspx?mfr=true
回答by YIN SHAN
Java on windows does NOT support unicode ouput by default. I have written a workaround method by calling Native API with JNA library.The method will call WriteConsoleW for unicode output on the console.
Windows 上的 Java 默认不支持 unicode 输出。我通过使用 JNA 库调用 Native API 编写了一个变通方法。该方法将调用 WriteConsoleW 以在控制台上输出 unicode。
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);
}
}
}