如何指定与基础Windows代码页一致的Java file.encoding值?

Rob*_*edy 7 java windows batch-file codepages

我有一个Java应用程序,使用一个接收器通过套接字接收数据InputStreamReader.它从其getEncoding方法报告"Cp1252" :

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

这不一定与系统报告的代码页相匹配.例如:

C:\>chcp
Active code page: 850

应用程序可以接收字节0x81,其在代码页850中表示字符ü.程序用代码页1252解释该字节,该代码页没有定义该值的任何字符,所以我得到一个问号.

通过在启动应用程序的批处理文件中添加另一个命令行选项,我能够为一个使用代码页850的客户解决此问题:

java.exe -Dfile.encoding=Cp850 ...

但当然,并非所有客户都使用代码页850.如何让Java使用与底层Windows系统兼容的代码页?我的偏好是我可以放在批处理文件中,保持Java代码不变:

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

McD*_*ell 6

cmd.exeis 使用的默认编码Cp850(或任何"OEM"CP是OS本机的); 系统编码是Cp1252(或任何"ANSI"CP是OS本机的).这里有血腥的细节.发现控制台编码的一种方法是通过本机代码执行此操作(有关当前控制台编码,请参阅GetConsoleOutputCP ; 有关默认"ANSI"编码,请参阅GetACP ; 等等).

通过-D交换机更改编码将影响所有默认编码机制,包括重定向的stdout/stdin/stderr.这不是一个理想的解决方案.

我想出了这个可以将控制台设置为系统ANSI代码页的WSH脚本,但还没弄清楚如何以编程方式切换到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
Run Code Online (Sandbox Code Playgroud)

(这是我的第一个WSH脚本,所以它可能有缺陷 - 我不熟悉注册表读取权限.)

使用TrueType字体是使用ANSI/Unicode的另一个要求cmd.exe.在时间允许的情况下,我将看一个程序切换到更好的字体.


Yis*_*hai 5

关于代码snippit,正确的答案是使用适当的构造函数来进行正确的代码转换的InputStreamReader.这样,系统上的默认编码无关紧要,你知道你得到的正确编码与你在套接字上获得的编码相对应.

然后,如果需要,可以在写出文件时指定编码,而不是依赖于系统编码,但当然当他们在该系统上打开文件时可能会出现问题,但现代Windows系统支持UTF-8,所以你如果需要,可以用UTF-8写出文件(内部Java将所有字符串表示为16位unicode).

我认为这是一般的"正确"解决方案,它与最大范围的底层系统最兼容.


Gre*_*00k 5

如果从 chcp 命令返回的代码页值将返回您需要的值,您可以使用以下命令来获取代码页

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

这将变量 CodePage 设置为从 chcp 返回的代码页值

C:\>echo %CodePage%
437
Run Code Online (Sandbox Code Playgroud)

您可以在 bat 文件中使用此值,方法是在其前面加上 Cp 前缀

C:\>echo Cp%CodePage%
Cp437
Run Code Online (Sandbox Code Playgroud)

如果将其放入 bat 文件中,则第一个命令中的 %I 值需要替换为 %%I