使用BufferedReader时,进程构建器的Java输出被覆盖

使用BufferedReader时,进程构建器的Java输出被覆盖,java,Java,我试图用Java运行一个外部程序并读取输出。该程序是C++中的Linux应用程序,运行数据挖掘算法并打印标准输出上找到的模式。我希望能够从Java应用程序中读取该输出,并使用表显示模式。问题是输出的大小相当大(作为测试,它在大约30秒内产生6.5MB)。我正在使用ProcessBuilder并使用InputStreamReader读取输出,InputStreamReader使用BufferedReader进行缓冲,正如您在以下代码中看到的: String[] cmd = {"./cl

我试图用Java运行一个外部程序并读取输出。该程序是C++中的Linux应用程序,运行数据挖掘算法并打印标准输出上找到的模式。我希望能够从Java应用程序中读取该输出,并使用表显示模式。问题是输出的大小相当大(作为测试,它在大约30秒内产生6.5MB)。我正在使用ProcessBuilder并使用InputStreamReader读取输出,InputStreamReader使用BufferedReader进行缓冲,正如您在以下代码中看到的:

      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;
         ...
      }
问题是输出被破坏了。当我在控制台上执行相同的程序时,输出是正确的,但是当我使用Java应用程序时,一些行被合并。更准确地说,输出应该是这样的

      TMEmulation log_pseduo_allocation (34985) (2 45 76 89 90)
      __divw clock timer (8273) (4 6 67 4 2)
但它是这样的

      TMEmulation log_pseduo_allocation (34985) (2__divw 45clock 76timer (89 8273) 904) (6 67 4 2)
你知道可能的问题吗

提前多谢了,
Patricia

您应该在单独的线程中阅读stdout和stderr,以避免阻塞问题。 我不能肯定这是否能解决您的问题,但无论如何都应该这样做,以避免您遇到其他问题(例如,您的应用程序可能会在stdout上死锁)

幸运的是,有一个非常好的示例,其中包含示例代码,可以引导您完成此过程。

文章指出(见第2页底部),即使不需要输出来防止可能的死锁,也应该始终从stderr和stdout中读取

由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此未能及时写入子流程的输入流或读取子流程的输出流可能会导致子流程阻塞,甚至死锁


<>尝试调用C++程序,选项为>代码> IOLBF。暴露在C++中的管道的末端可能是未缓冲的,而当您从命令行运行程序时,使用<代码> <代码>,它是行缓冲的。

与调用程序

的一些可能性。

1)如@ AtfFACTO表示C++程序输出可能不完全缓冲,所以调用SETVBUF使其一致。即第一个输出部分缓冲,第二个不缓冲,因此第一个在第二个输出结束后刷新。通常,如果从命令行和进程调用,缓冲可能会有所不同

2) 该程序是多线程的,当从java调用时,输出行为不同,因此输出计时也不同


基本上,您需要查看被调用程序的代码,以强制日志记录/输出都通过同一个调用。

如果您正在执行System.out.print()或其他任何操作,以便当前在每个迭代中进行调试,那么请尝试将所有迭代中的所有行放入一个字符串中,并尝试一下

也许您的输出方法是异步输出的。因此,您的打印输出可能已损坏,但不是您从输入流获得的输出


只是一个想法…

您能展示一下您如何处理读取行的代码吗?默认情况下getInputStream只读取stdout-stderr来自getErrorStream-或者如果您调用redirectErrorStream(true)关于ProcessBuilder实例从我对那篇文章的理解来看,即使您不需要输出,您也应该同时阅读这两篇文章,因为它们可能会导致死锁。但请注意,我们正在使用ProcessBuilder来设置流程,以便为您进行管理。投票结果为上,投票结果为下@标记它不是为您管理的,您必须读取两个流或合并它们。您是对的,程序是多线程的,并且计时影响了输出。添加同步解决了这个问题。谢谢