将命令行 unicode 参数传递给 Java 代码

2022-09-03 06:48:45

我必须将日语的命令行参数传递给Java主方法。如果我在命令行窗口中键入Unicode字符,它显示“?????”,这是可以的,但是传递给java程序的值也是“?????”。如何获取命令窗口传递的参数的正确值?下面是将命令行参数提供的值写入文件的示例程序。

public static void main(String[] args) {
        String input = args[0];
        try {
            String filePath = "C:/Temp/abc.txt";
            File file = new File(filePath);
            OutputStream out = new FileOutputStream(file);
            byte buf[] = new byte[1024];
            int len;
            InputStream is = new ByteArrayInputStream(input.getBytes());
            while ((len = is.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
            out.close();
            is.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

答案 1

不幸的是,您无法在使用Windows C运行时的stdlib的命令行应用程序中可靠地使用非ASCII字符,例如Java(以及几乎所有非Windows特定的脚本语言)。

这是因为默认情况下,他们使用特定于区域设置的代码页读取输入和输出,这永远不会是 UTF,这与使用 UTF-8 的其他所有现代操作系统不同。

虽然您可以使用该命令将终端的代码页更改为其他内容,但对 UTF-8 编码的支持在一些方面被破坏,这些方式可能会致命地使应用程序瘫痪。chcpchcp 65001

如果只需要日语,则可以通过将区域设置(区域设置中的“非 Unicode 应用程序的语言”)设置为日本来切换到代码页 932(类似于 Shift-JIS)。但是,对于不在该代码页中的字符,这仍将失败。

如果需要在 Windows 上通过命令行可靠地获取非 ASCII 字符,则需要直接调用 Win32 API 函数以避免编码到系统代码页层。也许你想用JNA来做到这一点。GetCommandLineW


答案 2

不幸的是,标准的Java启动器在Windows上处理Unicode命令行参数时存在一个已知且长期存在的错误。也许在其他一些平台上也是如此。对于Java 7 update 1,它仍然在原地。

如果您擅长用C / C++编程,则可以尝试编写自己的启动器。一些专门的发射器可能没什么大不了的...只需查看 JNI 调用 API 页面上的初始示例即可。

另一种可能性是使用 Java 包装器和临时文件的组合将 Unicode 参数传递给 Java 应用程序。请参阅我的博客Java,Xalan,Unicode命令行参数...以获取更多注释和包装器代码。