繁体   English   中英

使用java获取进程的输出结果

[英]Get the output result of a process with java

我想执行一段时间的进程,然后获取输出并销毁进程。 这是我的代码

BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader temp;
p.waitFor(7, TimeUnit.SECONDS);
temp=stdInput;
p.destroy(); 
System.out.println(temp.readLine());

但我得到了结果

java.io.IOException: Stream closed

如何在执行过程7秒后复制结果? 如果我使用此代码

p.waitFor(7, TimeUnit.SECONDS);
while ((inputRead=stdInput.readLine()) != null){
    Helper.log(inputRead);
}

while循环永远不会终止,因为进程在waitFor之后仍然存在,所以我必须销毁它。 如果我破坏了这个过程,我就不能再获得stdInput的内容了。

你不希望调用waitFor()因为它等待进程被销毁。 只要InpuutStream处于打开状态,您也不想阅读,因为只有在进程被终止时才会终止此类读取。

相反,您可以简单地启动该过程,然后等待7秒钟。 一旦7秒过去,读取缓冲区中的可用数据,而不等待流关闭:

BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
Thread.sleep(7000); //Sleep for 7 seconds
while (stdInput.ready()) { //While there's something in the buffer
     //read&print - replace with a buffered read (into an array) if the output doesn't contain CR/LF
    System.out.println(stdInput.readLine()); 
}
p.destroy(); //The buffer is now empty, kill the process.

如果进程继续打印,那么stdInput.ready()总是返回true,你可以尝试这样的事情:

BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
char[] buffer = new char[16 * 1024]; // 16 KiB buffer, change size if needed
long startedReadingAt = System.currentTimeMillis(); //When did we start reading?
while (System.currentTimeMillis() - startedReadingAt < 7000) { //While we're waiting
    if (stdInput.ready()){
        int charsRead = stdInput.read(buffer); //read into the buffer - don't use readLine() so we don't wait for a CR/LF
        System.out.println(new String(buffer, 0, charsRead));  //print the content we've read
    } else {
        Thread.sleep(100); // Wait for a while before we try again
    }
}
p.destroy(); //Kill the process

在这个解决方案中,线程不是休眠,而是从InputStream读取接下来的7秒,然后关闭进程。

java.io.IOException: Stream closed这可能是因为你在temp.readLine()之后调用了p.destroy()

问题似乎是该进程不会在您要检索的部分之后添加新的行终止。 要解决这个问题,您可以用小块而不是逐行读取程序的输出。

这是一个例子:

try(InputStream is = p.getInputStream()){
    byte[] buffer = new byte[10];
    String content = "";
    for(int r = 0; (r = is.read(buffer))!=-1;){
        content+=new String(buffer, 0, r);
        if(content.equals("all content")){// check if all the necessary data was retrieved.
            p.destroy();
            break;
        }
    }
}catch(Exception e){
    e.printStackTrace();
}

如果您知道程序输出的确切格式,更好的解决方案是使用扫描仪。

try(Scanner sc = new Scanner(p.getInputStream())){
    while(sc.hasNext()){
        String word = sc.next();
    }
}catch(Exception e){
    e.printStackTrace();
}

上面的例子将一次读取程序的输出一个字。

从您的评论看来,问题是该过程永远不会自行终止,您的程序永远不会退出while循环。

要解决这个问题,您可以使用计时器在一段时间后销毁进程,这是一个示例:

Timer t = new Timer();
t.schedule(new TimerTask() {
    @Override
    public void run() {
        p.destroy();
        t.cancel();
        t.purge();
    }
}, 7000);

try(BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));){
    while ((inputRead=stdInput.readLine()) != null){
        ...
    }
}catch(Exception e){
    e.printStackTrace();
}

请记住,此方法将始终导致stdInput.readLine()抛出异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM