使用BufferedReader时,来自进程buider的Java输出将被覆盖

问题描述

|| 我正在尝试使用Java运行外部程序并读取输出。该程序是C ++中的Linux应用程序,它运行数据挖掘算法并打印在标准输出中找到的模式。我希望能够从Java应用程序读取该输出并使用表格显示模式。问题在于输出的大小很大(作为测试,它在大约30秒内产生6.5MB)。我正在使用ProcessBuilder,并使用通过BufferedReader缓冲的InputStreamReader读取输出,如以下代码所示:
      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)
对可能的问题有任何想法吗? 提前多谢 帕特里夏     

解决方法

与被调用程序有关的几种可能性 1)@Artefacto表示C ++程序输出可能未完全缓冲,因此请调用setvbuf使其一致。也就是说,第一个输出部分缓冲,第二个则不缓冲,因此在第二个结束后首先刷新。通常,从命令行和进程调用缓冲可能会有所不同。 2)程序是多线程的,从Java调用时输出行为不同,因此输出时序不同。 基本上,您需要查看被调用程序的代码以强制通过同一调用进行日志记录/输出。     ,尝试使用选项
_IOLBF
在C ++程序program3ѭ中调用。暴露给C ++的管道末端可能没有缓冲,而当您从命令行使用
|
运行程序时,其行已缓冲。     ,如果您正在执行System.out.print()或当前在每次迭代中进行调试,请尝试将所有迭代中的所有行放入一个String中,然后尝试一下。 也许您的输出方法是异步打印出来的。因此,您的打印输出可能已损坏,但不是输入流中的输出。 只是一个主意...     ,您应该在单独的线程中读取stdout和stderr,以避免阻塞问题。 我不能肯定地说这是否可以解决您的问题,但是无论如何都应该这样做,以避免您可能遇到的其他问题(例如,您的应用可能在等待标准输出时死锁)。 幸运的是,这里有一个很好的示例代码示例,它带您逐步完成。 http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html 本文指出(请参阅第2页的底部),即使不需要输出来防止可能的死锁,也应始终从stderr和stdout中读取。   由于某些本机平台仅为标准输入和输出流提供了有限的缓冲区大小,因此未能及时写入子进程的输入流或读取子进程的输出流可能导致子进程阻塞,甚至死锁。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...