Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用java获取进程的输出结果_Java_Processbuilder - Fatal编程技术网

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

使用java获取进程的输出结果,java,processbuilder,Java,Processbuilder,我想执行一个进程一段时间,然后得到输出并销毁该进程。这是我的密码 BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream())); BufferedReader temp; p.waitFor(7, TimeUnit.SECONDS); temp=stdInput; p.destroy(); System.out.println(temp.readLine()); 但我得到的结果是

我想执行一个进程一段时间,然后得到输出并销毁该进程。这是我的密码

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
的内容

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

问题似乎是该过程没有在要检索的零件之后添加新行终止。要解决这个问题,您可以将程序的输出分成小块,而不是逐行读取

以下是一个例子:

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();
}
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();
}
如果您知道程序输出的确切格式,更好的解决方案是使用扫描仪

try(Scanner sc = new Scanner(p.getInputStream())){
    while(sc.hasNext()){
        String word = sc.next();
    }
}catch(Exception e){
    e.printStackTrace();
}
上面的示例将一次读取一个字的程序输出

从您的评论来看,问题似乎在于进程从未自行终止,并且您的程序从未退出
while
循环

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

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();
}
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()
引发异常。

您不希望调用
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
BufferedReader stdInput=newbufferedReader(newInputStreamReader(p.getInputStream());
char[]buffer=新字符[16*1024];//16 KiB缓冲区,如果需要,更改大小
long startedReadingAt=System.currentTimeMillis()//我们什么时候开始读书的?
while(System.currentTimeMillis()-startedReadingAt<7000){//,我们正在等待
if(stdInput.ready()){
int charsRead=stdInput.read(buffer);//读入缓冲区-不要使用readLine(),这样我们就不会等待CR/LF
System.out.println(新字符串(buffer,0,charsRead));//打印我们读过的内容
}否则{
Thread.sleep(100);//请稍等片刻,然后再试一次
}
}
p、 破坏()//终止进程

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

问题不在于换行符,而是他在
输入流
打开时一直读取,直到进程被终止。此外,他可能不知道所有内容是什么。OP只是尝试读取进程在这7秒内打印出来的任何内容。我尝试了你的代码,如果进程不返回任何输出,它永远不会终止。它还返回java.io.IOException:如果进程返回的outputreadLine()不够,流是否关闭?当readLine()返回true时,您认为ready()可能返回false?while循环永远不会终止,因为在进程停止之前,缓冲区中总会有一些内容需要读取
p.waitFor(7,TimeUnit.SECONDS)
将线程阻塞
7
秒或直到进程终止,因此无需将该调用替换为
thread.sleep(7000)
@Titus我不会调用
p.waitFor()
,因为那样会永远阻塞(直到进程被破坏)!我知道你没有调用
p.waitFor()
,但是你已经替换了
p.waitFor(7,TimeUnit.SECONDS)
线程睡眠(7000)这是不必要的。