簡體   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