【问题标题】:How to write a byte array to OutputStream of process builder (Java)如何将字节数组写入流程构建器(Java)的OutputStream
【发布时间】:2011-07-04 10:36:26
【问题描述】:
byte[] bytes = value.getBytes();
Process q = new ProcessBuilder("process","arg1", "arg2").start();
q.getOutputStream().write(bytes);
q.getOutputStream().flush();
System.out.println(q.getInputStream().available());

我正在尝试将文件内容流式传输到可执行文件并捕获输出,但输出(InputStream)始终为空。如果我指定文件位置但不使用流式输入,我可以捕获输出。

我该如何克服这个问题?

【问题讨论】:

  • 您还没有告诉我们问题出在哪里。您正在写入的过程需要从标准中读取 - 是吗?
  • 对不起,整个程序挂了。我认为它可能陷入僵局。这可能是由于数据 5 - 10 mb(日志文件)的大型性质
  • 你确定你从ProcessBuilder得到的InputStream支持available方法吗?大多数实现不支持这一点,只返回 0。

标签: java io iostream


【解决方案1】:

尝试使用BufferedInputStream()BufferedOutputStream() 包装您的流:

http://download.oracle.com/javase/6/docs/api/java/lang/Process.html#getOutputStream%28%29

实现说明:最好对输出流进行缓冲。

实现说明:缓冲输入流是个好主意。

即使使用缓冲流,如果您正在处理大量数据,缓冲区仍然有可能被填满,您可以通过启动一个单独的线程来从q.getInputStream() 读取来处理这个问题,所以您仍然可以在写入进程时从进程中读取。

【讨论】:

    【解决方案2】:

    也许您执行的程序只有在检测到输入数据结束时才开始工作。这通常通过等待 EOF(文件结束)符号来完成。您可以通过关闭进程的输出流来发送它:

    q.getOutputStream().write(bytes);
    q.getOutputStream().close();
    

    在等待过程的同时试试这个。

    【讨论】:

      【解决方案3】:

      我不知道这里是否还有其他问题,但是其他进程(“进程”)甚至没有时间响应,您没有等待它(方法available()不会阻塞)。要尝试这一点,您可以先在 flush() 之后插入 sleep(2000),如果可行,您应该切换到查询 q.getInputStream().available() multiple 次短中间停顿。

      【讨论】:

      • 不,这没有帮助。来自该进程的流式输出正被送入 csv 解析器。解析器是否有可能在生成输出时对其进行处理,或者在从流中读取之前必须完成该过程。
      • 我还尝试循环写入流,因为我认为数据的大小可能是问题所在。这产生了一个损坏的管道错误消息。
      • 你写“来自进程的流输出被输入到 csv 解析器”:这让我觉得被调用的程序(“进程”)根本不产生标准输出/控制台输出。尝试用您知道它会产生控制台输出的程序替换“进程”,例如在 Windows 上“help.exe”
      【解决方案4】:

      我认为,您必须等待,直到该过程完成。 我是这样实现的:

      public class ProcessReader {
      
        private static final int PROCESS_LOOP_SLEEP_MILLIS = 100;
        private String result;
      
        public ProcessReader(Process process) {
          BufferedReader resultReader = new BufferedReader(new   InputStreamReader(process.getInputStream()));
          StringBuilder resultOutput = new StringBuilder();
          try {
              while (!checkProcessTerminated(process, resultReader, resultOutput)) {
              }
          } catch (Exception ex1) {
              throw new RuntimeException(ex1);
          }
          result = resultOutput.toString();
      }
      
      public String getResult(){
          return result;
      }
      
      private boolean checkProcessTerminated(Process process, BufferedReader resultReader, StringBuilder resultOutput) throws Exception {
      
          try {
              int exit = process.exitValue();
              return true;
          } catch (IllegalThreadStateException ex) {
              Thread.sleep(PROCESS_LOOP_SLEEP_MILLIS);
          } finally {
              while (resultReader.ready()) {
                  String out = resultReader.readLine();
                  resultOutput.append(out).append("\n");
              }
          }
          return false;
      }
      

      }

      我现在刚刚删除了一些您不需要的特定代码,但它应该可以工作,试试吧。 问候

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-03
        • 1970-01-01
        • 1970-01-01
        • 2015-07-05
        • 1970-01-01
        • 2010-12-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多