【问题标题】:Fetch and store output from a subprocess in Java从 Java 中的子进程获取和存储输出
【发布时间】:2011-09-28 08:27:13
【问题描述】:

我正在做一些需要我开始子进程(命令提示符)并在其上执行一些命令的事情。我需要从子进程中获取输出并将其存储在文件或字符串中。 这是我到目前为止所做的,但它不起作用:

public static void main(String args[])
{
        try
    {
        Runtime RT = Runtime.getRuntime();
        String command = "cmd /c start javap java.lang.String"; 
        File file = new File("write.txt");
        Writer output = new BufferedWriter(new FileWriter(file));
            BufferedReader br = new(BufferedReader(newInputStreamReader(RT.exec(command).getInputStream()));
        String temp = br.readLine();
        while(!temp.equals(null))
        {
            output.write(temp);
            temp = br.readLine();
        }
        output.close();
        RT.exec("exit");
    }
    catch(Exception e)
    {
        System.out.println(e);
    }
}

【问题讨论】:

  • 不起作用是什么?有什么错误?你期待什么?更详细
  • 就像我想要的那样,当新的命令提示符打开并执行 javap java.lang.String 时,它应该存储在 write.txt 中。但我得到的只是一个空白的 write.txt。

标签: java subprocess runtime.exec


【解决方案1】:

开始改变这个:

new(BufferedReader(newInputStreamReader(

收件人:

new BufferedReader(new InputStreamReader(

编译看看是否还有问题

编辑

另外,你不应该捕捉异常是有充分理由的,你也会捕捉到像NullPointerException这样的编程错误

 while( !temp.equals(null)) { //Throws NullPointerExceptin when temp is null

改变它:

 while( temp != null ) { //!temp.equals(null)) {

最后,您不必“退出”,因为您真的不在 cmd 中。

修正版

此版本按您的意愿运行:

import java.io.*;
class Rt { 
  public static void main(String args[]) throws Exception {
          Runtime RT = Runtime.getRuntime();
          String  command =  "javap java.lang.String" ; 
          File file = new File("write.txt");
          Writer output = new BufferedWriter(new FileWriter(file));
          BufferedReader br = new BufferedReader(new InputStreamReader(RT.exec(command).getInputStream()));
          String temp = br.readLine();
          while( temp != null ) { //!temp.equals(null)) {
              output.write(temp);
              temp = br.readLine();
          }
          output.close();
          //RT.exec("exit");
  }
}

编辑 最后的评论:

从 Java 1.5 开始,调用命令的首选方式是使用 ProcessBuilder,最好使用字符串数组而不是单个字符串(或 varargs )。

当您构建输出时,您可以摆脱文件对象并将文件名直接传递给文件编写器。

在阅读该行时,您可以在条件中分配和评估。

Java 的编码约定建议使用相同的左大括号。

这将是我的代码版本:

class Rt { 
   public static void main(String args[]) throws Exception {

      Writer output     = new BufferedWriter(new FileWriter ( "write.txt"));
      InputStream in    = new ProcessBuilder("javap", "java.lang.String").start().getInputStream();
      BufferedReader br = new BufferedReader( new InputStreamReader(in)); 
      String line = null;
      while( ( line = br.readLine() )   != null ) {
          output.write( line );
      }
      output.close();
  }
}

它可能还需要一些工作,但我希望它可以帮助你。

【讨论】:

  • 抱歉,我在这里复制代码时出错了 :) 问题仍然存在 :)
  • @Kazekage 您的原始代码中有许多错误。请参阅上面的更正版本和建议。
  • 更正后的版本仍然给我一个空白的 write.txt,而另一个版本给我一个 IOException 说无法运行程序“javap”:CreateProcess error=2。
  • 你必须努力编译你自己的代码。在这方面我无能为力。这是使用该代码的会话记录(您甚至不需要编辑器来复制它)gist.github.com/1063873
  • @Kazekage 不要指望一个可行的解决方案。试着自己找出问题所在。获取代码和想法并尝试修复您的代码,或根据您的需要对其进行调整。人们不会用勺子喂你。顺便说一句,以上工作。
【解决方案2】:

这是一个应该可以工作的例子:

        StringBuffer outStream = new StringBuffer();
        StringBuffer errStream = new StringBuffer();
        Runtime runtime = Runtime.getRuntime();

        Process process = null;
        try {
            process = runtime.exec(command);
        } catch (IOException ex) {
            ex.printStackTrace();
            return;
        }

        InputStream outIs = process.getInputStream();
        MonitorOutputThread sout = new MonitorOutputThread(outIs, outStream);
        sout.run();

        InputStream errIs = process.getErrorStream();
        MonitorOutputThread serr = new MonitorOutputThread(errIs, errStream);
        serr.run();

        while (sout.isAlive() || serr.isAlive()) {
            try {
                sleep(100);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
                // ignore
            }
        }

还有 MonitorOutputThread 的代码

private class MonitorOutputThread extends Thread {

    private final InputStream is;
    private final StringBuffer output;

    public MonitorOutputThread(InputStream is, StringBuffer output) {
        this.is = is;
        this.output = output;
    }

    @Override
    public void run() {
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);

        String line = null;
        try {
            while ((line = br.readLine()) != null) {
                output.append(line);
                output.append(LINE_SEPARATOR);
            }

            if (output.length() >= 1) {
                char lastChar = output.charAt(output.length() - 1);

                if (lastChar == '\n') {
                    output.deleteCharAt(output.length() - 1);
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
            return;
        }
    }

}

这应该捕获命令的标准输出和标准错误。

【讨论】:

  • 我认为这个例子太复杂了。我认为你也应该加入主题。
  • 是的,它有点复杂。你是对的。
【解决方案3】:

DevDaily 有一个 simple example 如何使用 Process 类。
见sn-p:

import java.io.*;

public class JavaRunCommand {

    public static void main(String args[]) {
        String s = null;

        try {

            // run the Unix "ps -ef" command
            // using the Runtime exec method:
            Process p = Runtime.getRuntime().exec("ps -ef");

            BufferedReader stdInput = new BufferedReader(new 
                 InputStreamReader(p.getInputStream()));

            BufferedReader stdError = new BufferedReader(new 
                 InputStreamReader(p.getErrorStream()));

            // read the output from the command
            System.out.println("Here is the standard output of the command:\n");
            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }

            // read any errors from the attempted command
            System.out.println("Here is the standard error of the command (if any):\n");
            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }

            System.exit(0);
        }
        catch (IOException e) {
            System.out.println("exception happened - here's what I know: ");
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

或者甚至检查this code我前段时间写的

【讨论】:

  • 当我将它用于 Windows 中命令提示符上的命令 javap java.lang.String 时,我得到空白输出到此代码
猜你喜欢
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 2012-03-06
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多