[英]Java output from process buider overwritten when using BufferedReader
I'm trying to run an external program in Java and to read the output.我正在尝试在 Java 中运行外部程序并读取 output。 The program is a Linux application in C++ that runs a data mining algorithm and prints the patterns found on standard output.
该程序是 C++ 中的 Linux 应用程序,它运行数据挖掘算法并打印在标准 output 上找到的模式。 I want to be able to read that output from my Java app and to show the patterns using a table.
我希望能够从我的 Java 应用程序中读取 output 并使用表格显示模式。 The problem is that the size of the output is quite big (as a test it produces 6.5MB in about 30 seconds).
问题是 output 的大小相当大(作为测试,它在大约 30 秒内产生 6.5MB)。 I'm using ProcessBuilder and reading the output using an InputStreamReader buffered using a BufferedReader as you can see in the following code:
我正在使用 ProcessBuilder 并使用使用 BufferedReader 缓冲的 InputStreamReader 读取 output,如以下代码所示:
String[] cmd = {"./clogen_periodic", selected, support, "-t 4"};
Process p = new ProcessBuilder(cmd).start();
input = new BufferedReader (new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
...
process line;
...
}
The problem is that the output gets corrupted.问题是 output 已损坏。 When I execute the same program on a console the output is correct but when I use the Java app some lines are merged.
当我在控制台上执行相同的程序时,output 是正确的,但是当我使用 Java 应用程序时,一些行被合并了。 More precisely output should be like this
更准确地说 output 应该是这样的
TMEmulation log_pseduo_allocation (34985) (2 45 76 89 90)
__divw clock timer (8273) (4 6 67 4 2)
but it is like this但就是这样
TMEmulation log_pseduo_allocation (34985) (2__divw 45clock 76timer (89 8273) 904) (6 67 4 2)
Any idea about the possible problem?对可能的问题有任何想法吗?
Thanks a lot in advance, Patricia非常感谢,帕特里夏
A few possibilities all to do with the called program与被调用程序有关的一些可能性
1) as @Artefacto says the C++ program output might not be fully buffered so call setvbuf to make it consistant. 1) 正如@Artefacto 所说,C++ 程序 output 可能没有完全缓冲,因此调用 setvbuf 使其一致。 ie the first output is partially buffered and second is not and so first flushes after the end of the second.
即第一个 output 被部分缓冲,第二个不是,所以在第二个结束后第一次刷新。 In general buffering can differ if called from the command line and from a process.
一般来说,如果从命令行和进程调用,缓冲可能会有所不同。
2) The program is multi-threaded and the output behaves differently when called from java and so the output timing differs. 2)程序是多线程的,当从 java 调用时,output 的行为不同,因此 output 时序不同。
Basically you need to look at the code for the called program to force logging/output to be all through the same call.基本上,您需要查看被调用程序的代码,以强制记录/输出全部通过同一个调用。
You should be reading stdout and stderr in separate threads to avoid blocking issues.您应该在单独的线程中读取 stdout 和 stderr 以避免阻塞问题。 I can't say for sure if that will fix your problem but it should be done anyway to avoid other problems you may hit (your app may deadlock waiting on stdout for example).
我不能确定这是否会解决您的问题,但无论如何都应该这样做以避免您可能遇到的其他问题(例如,您的应用程序可能会死锁等待标准输出)。
Luckily there's a very good example with sample code that walks you through this.幸运的是,有一个非常好的示例代码可以引导您完成此操作。 http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
The article states (see bottom of page 2) that you should always read from stderr and stdout even if you don't need the output to prevent possible deadlocks.文章指出(见第 2 页底部),即使您不需要 output 来防止可能的死锁,您也应该始终从 stderr 和 stdout 读取。
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.
Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.
If you're doing a System.out.print() or what ever for debugging in every iteration currently, then try putting all lines from all iterations into one String and give that a try.如果您正在执行 System.out.print() 或当前在每次迭代中进行调试的任何操作,请尝试将所有迭代中的所有行放入一个字符串中并尝试一下。
Maybe your output method prints out asynchronously.也许您的 output 方法会异步打印出来。 Therefore your printed output may be corrupted but not the one you got from input stream.
因此,您打印的 output 可能已损坏,但不是您从输入 stream 获得的损坏。
Just an idea...只是一个想法...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.