简体   繁体   English

Java output 在使用 BufferedReader 时被覆盖

[英]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.

Try calling in C++ program, setvbuf with the option _IOLBF .尝试在 C++ 程序中调用, setvbuf带有选项_IOLBF The end of the pipe exposed to the C++ is probably unbuffered, while when you run the programs from the command line with |暴露给 C++ 的 pipe 的结尾可能是无缓冲的,而当您从命令行运行程序时使用| , it's line buffered. ,它是行缓冲的。

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.

相关问题 java进程buider无法获得输出 - java process buider failed to get output 在Java输入/输出流上使用BufferedReader时,readline()会阻塞 - readline() blocks when using BufferedReader over Java input/output streams 杀死Java进程时关闭BufferedReader和BufferedWriter - Closing BufferedReader and BufferedWriter when killing Java process 如何从Java的进程输出中实时读取BufferedReader? - How do I read from BufferedReader real-time from a process output in Java? 使用Java bufferedReader从URL获取html - Using Java bufferedreader to get html from URL 从process.getErrorStream()读取时,BufferedReader阻塞 - BufferedReader blocking when reading from process.getErrorStream() 为什么Java BufferedReader错过输出 - why java BufferedReader miss output 确保值不为空后,在使用 BufferedReader 时如何防止 Java 中发生 NullPointer 异常? - How to prevent NullPointer Exception from occuring in Java when using BufferedReader after making sure value is not null? 从C程序读取输出时BufferedReader挂起 - BufferedReader hangs when reading output from a C program Java BufferedReader 的 readLine() 缓慢获取 ProcessBuilder 的进程 output on Windows - Java BufferedReader's readLine() slow to get ProcessBuilder's process output on Windows
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM