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

时间:2019-03-17 16:14:26

标签: java io outputstream

我试图从Java(使用# cat infile | /path/to/src/redis-cli (error) ERR unknown command `--verbose`, with args beginning with: `--cluster`, `create`, `redis.slave.1:6379`, `redis.master.1:6379`, `--cluster-replicas`, `1`, # /path/to/src/redis-cli < infile (error) ERR unknown command `--verbose`, with args beginning with: `--cluster`, `create`, `redis.slave.1:6379`, `redis.master.1:6379`, `--cluster-replicas`, `1`, )运行一个简单的echo程序,有一个无限循环,其中我从用户(使用ProcessBuilder)获得输入。然后,我使用Scanner将其写入进程的stdin,并且希望看到通过stdout回显相同的字符串,但是除非关闭流(我不想这样做),否则它不会出现。我写了一个长字符串。甚至在调用flush时,如果字符串很短(例如1个字符),它将不起作用。

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

OutputStreamWriter

编辑3/18:我已经尝试使用Windows sysinternals工具来跟踪写入syscall,并且确实看起来像我的猜测是正确的,刷新不会起作用,除非它是长字符串(或者除非您关闭流)。
编辑3/19:我发现了这一点:Does fgets() locks stdout preventing printf使事情变得更加有趣。

2 个答案:

答案 0 :(得分:1)

问题出在与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

答案 1 :(得分:0)

由于以下问题,该问题终于得以解决:
Does fgets() locks stdout preventing printf
因此,问题实际上不是Java的错,这是Windows的特质之一,在这里,因为我已经将流连接到stdin和stdout,并且虽然我没有关闭stdin,但它没有写到stdout。
因此,解决方案:1)在“ a.exe”侧刷新标准输出。或2)只是不要同时使用两个流。例如,在“ a.exe”端而不是stdout写入文件,而在Java端从该文件使用。
如果您可以访问“ a.exe”,则(1)是更好的选择,但这可能是您无权访问的外部程序。