首页 > 解决方案 > Java:Windows 上的 Runtime.exec() 和 Unicode 符号:如何使其与非英文字母一起使用?

问题描述

介绍

我正在使用Runtime.exec()来执行一些外部命令,并且我正在使用包含非英文字符的参数。我只是想运行这样的东西: python test.py шалом

它直接在 cmd 中正常工作,但通过错误处理 Runtime.exec.getRuntime()("python test.py шалом")

在 Windows 上,我的外部程序由于传递给它的未知符号而失败。

我记得2010 年代初的类似问题(!) - JDK-4947220,但我认为它自 Java 核心 1.6 以来已经修复。

环境:

操作系统:名称 Microsoft Windows 10 Pro(版本 10.0.18362 Build 18362)

Java: jdk1.8.0_221

代码

要理解这个问题 - 最好的方法是使用下面列出的代码片段:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class MainClass {
    private static void foo(String filename) {
        try {
            BufferedReader input = new BufferedReader(
                    new InputStreamReader(
                            Runtime.getRuntime().exec(filename).getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                System.out.println(line);
            }
            input.close();
        } catch (Exception e) { /* ... */ }
    }

    public static void main(String[] args) {
        foo("你好.bat 你好"); // ??
        foo("привет.bat привет"); // ??????
        foo("hi.bat hi"); // hi
    }
}

其中 .bat 文件仅包含简单@echo %1 的输出将是:

??
??????
hi

PS System.out.println("привет")- 工作正常并正确打印所有内容

问题如下:

1) 这个问题与 Utf-8 utf-16 格式有关吗?

2)如何解决这个问题?我不喜欢这个答案,因为它看起来是一个非常危险和丑陋的解决方法。

3)有谁知道为什么批处理文件的文件名没有被破坏并且可以找到这个文件,但是参数被破坏了?可能是问题@echo

标签: javawindowsbatch-fileunicode

解决方案


  1. 是的,问题与 UTF 有关。理论上,执行 bat 文件的设置 65001 代码页cmd应该可以解决问题(以及从 Java 端将 UTF-8 字符集设置为默认值)

  2. 不幸的是,Windows 中有一个错误,这里提到了Java、Unicode、UTF-8 和 Windows 命令提示符

  3. 所以没有简单而完整的解决方案。可以为 和 设置相同的默认语言特定编码,如 cp1251 javaCyrillic cmd。并非所有语言都很好地反映在 Windows 编码中,例如中文就是其中之一。

如果对 Windows 系统有一些非技术限制,将所有cmd进程的默认编码更改为特定于语言的编码,则 java 代码将更加复杂。在开始时,必须创建新的 cmd 进程,并且应该将带有 UTF-16LE(用于 `cmd /U' 进程)的读取器和来自不同线程的带有 CP1251 的写入器连接到它的 stdin/stdout 流。从 java 发送到标准输入的第一个命令应该是“chcp 1251”,第二个是 bat 文件的名称及其参数。

完整的解决方案仍然可以使用 UTF-16LE 读取 cmd 输出,但要传入文本,应使用其他通用编码,例如 base64,这再次导致复杂性增加


推荐阅读