【问题标题】:Cannot get the getInputStream from Runtime.getRunTime.exec()无法从 Runtime.getRunTime.exec() 获取 getInputStream
【发布时间】:2013-06-11 07:06:53
【问题描述】:
public class LinuxInteractor {

public static String executeCommand(String command)
{
System.out.println("Linux command: " + command);

try 
{
   Process  p = Runtime.getRuntime().exec(command);
   p.waitFor();
   BufferedReader bf=new BufferedReader(new InputStreamReader( p.getInputStream()));
   String str=bf.readLine();
   System.out.println("inputStream is::"+str);
   while( (str=bf.readLine()) != null)
   {
       System.out.println("input stream is::"+str);        
   }
   System.out.println("process started");
}
catch (Exception e) {
System.out.println("Error occured while executing Linux command. Error       Description: "
    + e.getMessage());
    e.printStackTrace();
}
}

当我通过控制台运行脚本时,它正在工作。但是通过 Java 程序 InputStream(Str)null

我还有其他方法可以使用吗?

【问题讨论】:

  • 1) 阅读(并实施)所有 When Runtime.exec() won't 的建议。那可能会解决问题。如果不是,它应该提供更多关于失败原因的信息。然后忽略它引用exec 并使用ProcessBuilder 构建Process。还将String arg 分解为String[] args 以说明本身包含空格的参数。 2) 我怀疑waitFor 调用应该在流消费之后。
  • 等待进程退出你读取它的任何输出之前有点没有意义。如果它的输出缓冲区满了,它就永远不会退出。您的代码中没有 InputStream(Str),但如果您声称 Process.getInputStream() 返回 null,则很难相信您是正确的。
  • @EJP InputStream is=Process.getInputStream;如果我通过 buffer-reader.its 读取它,它将为空。现在解决了,需要在另一个线程中进行。
  • 这没有意义。 InputStream 要么为空,要么不是。如果它为空,则根本无法“通过BufferedReader 阅读它”。你的意思是你用BufferedReader.readLine()读了一个空值?

标签: java process runtime.exec


【解决方案1】:

解决方案
您应该尝试在不同的线程上进行读取和执行。

更好的选择是使用 ProcessBuilder,它会为您处理“脏”工作。
try 块内的代码可能如下所示:

/* Create the ProcessBuilder */
ProcessBuilder pb = new ProcessBuilder(commandArr);
pb.redirectErrorStream(true);

/* Start the process */
Process proc = pb.start();
System.out.println("Process started !");

/* Read the process's output */
String line;             
BufferedReader in = new BufferedReader(new InputStreamReader(
        proc.getInputStream()));             
while ((line = in.readLine()) != null) {
    System.out.println(line);
}

/* Clean-up */
proc.destroy();
System.out.println("Process ended !");

另请参阅此short demo


问题原因
根据Java DocswaitFor()

如有必要,使当前线程等待,直到此 Process 对象表示的进程终止。

因此,您试图在进程终止后获取进程的输出流,因此是null


(抱歉对答案进行了重大修改。)

【讨论】:

  • 任何以 'try' 开头的内容都适合评论,不适合回答。
  • 没有 waitFor() 并且在处理输出之后,我试过了。但同样的问题来了。InputStream Stirng 为空。
  • 我知道 :) 这个答案是完全错误的,很快就会被删除。我只是好奇这个错误的答案可能会得到多少赞成票。抱歉,添麻烦了。您最好按照 Juned Ahsan 的建议在单独的线程中阅读它。
  • @sachingrover:我知道你已经解决了你的问题,但你可能想看看我更新的答案以寻找替代方案(拥有多种方法来解决问题总是一件好事问题);)
【解决方案2】:

您需要在单独的线程中执行此操作:

Process process = Runtime.getRuntime().exec(command);
LogStreamReader lsr = new LogStreamReader(process.getInputStream());
Thread thread = new Thread(lsr, "LogStreamReader");
thread.start();


public class LogStreamReader implements Runnable {

    private BufferedReader reader;

    public LogStreamReader(InputStream is) {
        this.reader = new BufferedReader(new InputStreamReader(is));
    }

    public void run() {
        try {
            String line = reader.readLine();
            while (line != null) {
                System.out.println(line);
                line = reader.readLine();
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

然后你需要第二个线程来处理输入。您可能希望像处理 stdout 一样处理 stderr。

【讨论】:

    猜你喜欢
    • 2013-10-10
    • 2013-01-14
    • 1970-01-01
    • 2011-11-12
    • 2016-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    相关资源
    最近更新 更多