我试图从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使事情变得更加有趣。
答案 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)是更好的选择,但这可能是您无权访问的外部程序。