Process.getInputStream()使用哪种编码?

rds*_*rds 6 java character-encoding

在Java程序中,我生成了一个新的Processvia ProcessBuilder.

args[0] = directory.getAbsolutePath() + File.separator + program;
ProcessBuilder pb = new ProcessBuilder(args);
pb.directory(directory);
final Process process = pb.start();
Run Code Online (Sandbox Code Playgroud)

然后,我用一个新的读取过程标准输出 Thread

new Thread() {
    public void run() {
        BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));
        String line = "";
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
    }
}.start();
Run Code Online (Sandbox Code Playgroud)

但是,当进程输出非ASCII字符(例如'é')时,则改为使用line字符'\uFFFD'.

InputStream返回的编码是什么getInputStream(我的平台是欧洲的Windows)?

如何更改line包含预期数据(即'\u00E9'for 'é')的内容?

编辑:我试过new InputStreamReader(...,"UTF-8"): é变成了\uFFFD

Thi*_*ilo 9

InputStream是二进制流,因此没有编码.创建Reader时,您需要知道要使用的字符编码,这取决于您调用的程序产生的内容(Java不会以任何方式转换它).

如果没有为InputStreamReader指定任何内容,它将使用平台默认编码,这可能不合适.还有另一个构造函数允许您指定编码.

如果你知道要使用什么编码(你真的必须知道):

new InputStreamReader(process.getInputStream(), "UTF-8") // for example
Run Code Online (Sandbox Code Playgroud)

  • UTF-8 * 不是 * Java 中的默认编码。根本没有默认值,它总是使用依赖于平台的东西(可以由环境变量和系统属性控制)。不是应用程序开发人员通常应该依赖的东西。最好始终明确您想要的编码。 (2认同)

jan*_*pol 6

有趣的是,在Windows上运行时:

ProcessBuilder pb = new ProcessBuilder("cmd", "/c dir");
Process process = pb.start();
Run Code Online (Sandbox Code Playgroud)

然后CP437代码页工作得很好

new InputStreamReader(process.getInputStream(), "CP437");
Run Code Online (Sandbox Code Playgroud)

  • 实际上,现在应该是CP850。奇怪的是,似乎所有的 windows 系统都设置为 windows-1252/cp1252(至少在西欧),但控制台专门使用 CP850。CP437是CP850的始祖。打开命令提示符并运行“chcp”应该会告诉您它使用哪种编码来打印字符数据。 (2认同)

kan*_*kan 4

据我了解,操作系统流是字节流,这里没有字符。构造InputStreamReader函数使用jvm默认字符集java.nio.charset.Charset#defaultCharset(),您可以使用另一个构造函数显式指定字符集。