繁体   English   中英

如何强制 java OutputStreamWriter 实际写入单个字节?

[英]How to force java OutputStreamWriter to actually write a single byte?

我正在尝试从 Java 运行一个简单的 echo 程序(使用ProcessBuilder ),有一个无限循环,我从用户那里获取输入(使用Scanner )。 然后我使用OutputStreamWriter将它写入进程的标准输入,我希望看到相同的字符串通过标准输出回显,但除非我关闭流(我不想这样做)或者我写了很长的细绳。 ven 调用flush 时,如果字符串很短(例如1 个字符),则它不起作用。

即使对于单个字符(短)字符串,我们如何强制刷新?

ProcessBuilder pb = new ProcessBuilder(cmd);
Process p = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
OutputStream stdin = p.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(stdin);
Scanner scanner = new Scanner(System.in);
String line;
while (true) {
    String input = scanner.nextLine();
    if (input.equals("q"))
        break;
    writer.write(input+"\n");
    writer.flush();
    // writer.close(); (uncommenting this makes it work once, then throw error)
    line = br.readLine();
    System.out.println(line);
}

编辑 3/18:我尝试过 windows sysinternals 工具来跟踪写入系统调用,看起来我的猜测确实是正确的,除非它是一个长字符串(或者除非您关闭流),否则刷新不起作用。
编辑 3/19:我发现了这一点: fgets() 是否锁定标准输出以防止 printf使事情变得更加有趣。

问题在于与a.exe的交互。

a.exe使用fgets 它在读取 (n-1) 个字符、读取换行符或到达文件结尾时停止,以先到者为准。

您没有将新行推送到a.exe ,因此fgets只能使用 EOF 完成,这会在您关闭流时发生。

您可以从 Java 推送行尾,也可以在 C 端使用另一个读取函数。

要推送行尾,您可以使用:

writer.write(System.lineSeparator());

请参阅: https : //www.tutorialspoint.com/c_standard_library/c_function_fgets.htm

由于这个问题,问题[终于]解决了:
fgets() 是否锁定标准输出以防止 printf
所以问题实际上不是java的错,它是windows的特性之一,因为我已经将流连接到stdin和stdout,虽然我没有关闭stdin,但它没有写入stdout。
所以解决方案:1)在“a.exe”端刷新标准输出。 或 2) 只是不要同时使用两个流。 例如,在“a.exe”端,而不是标准输出,写入文件,而在 java 端从该文件消费。
(1) 如果您有权访问“a.exe”,则是更好的选择,但这可能是您无权访问的外部程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM