给输入命令和Get命令提示符完成输出到textarea在Java中

时间:2013-12-18 02:41:20

标签: java cmd command execute prompt

我无法读取程序的完整输出,有时它会挂起界面并且不会完全编译。 在netbeans的输出控制台中,它显示完整的输出,但不显示在jtextarea中。

帮我先在cmd(命令提示符)中执行命令,然后从cmd读取输出到textarea。

在cmd中,命令可以快速执行并获得完整的结果。但我不知道如何从cmd获得结果。

这是我的代码:

String line;
String [] cmds={"xyz.exe","--version"};
try{
 Process p =Runtime.getRuntime().exec(cmds);                   
     p.waitFor();
     int val=p.exitValue();
     if(val==0)
     {
         b1.setForeground(Color.green);                              
         InputStream ins = p.getInputStream();
         InputStreamReader insr = new InputStreamReader(ins);
         BufferedReader br = new BufferedReader(insr);
         while ((line = br.readLine()) != null) {
           System.out.println( line);
           t1.setText( line);
         } 
     } else if(val==1)
     {
         b1.setForeground(Color.red);
         InputStream error = p.getErrorStream();
         InputStreamReader isrerror = new InputStreamReader(error);
         BufferedReader bre = new BufferedReader(isrerror);
         while ((line = bre.readLine()) != null) {
           t1.setText(line);

         }
     }
    } catch(IOException e){
        System.out.println("error");
        e.printStackTrace();
      } catch (InterruptedException ex) {
          Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }

1 个答案:

答案 0 :(得分:0)

我看到的问题是这个。您正在尝试执行程序,但您不是从程序的输出流(即Process的getInputStream())读取,直到它完成执行。因此,如果您的subProcess碰巧有大量输出并且耗尽了缓冲区,那么subProcess将被阻止。

因此,要解决您的问题,您需要在子进程仍在执行时绝对读取inputstream和errorstream以避免子进程被阻塞。您可以使用阻塞IO,这意味着您需要单独的线程来服务输出流和errorstream或非阻塞IO,您可以使用1个线程连续监视输出流和errorstream用于读取数据。

java.lang.Process上的Java Docs说

  

由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞,甚至死锁。

import java.io.*;
import java.nio.channels.*;
import java.nio.*;

public static void nioExecute() throws Exception {
    Process p = Runtime.getRuntime().exec("javac");
    ReadableByteChannel stdoutChannel = Channels.newChannel(p.getInputStream());
    ReadableByteChannel stderrChannel = Channels.newChannel(p.getErrorStream());
    ByteBuffer buffer = ByteBuffer.allocate(1000);

    StringBuilder stdOut = new StringBuilder();
    StringBuilder stdErr = new StringBuilder();

    while(stdoutChannel.isOpen() || stderrChannel.isOpen()) {
        buffer.clear();
        if(stderrChannel.isOpen()) {
            int bytesRead = stderrChannel.read(buffer);
            if(bytesRead>0) stdErr.append(new String(buffer.array(),0,bytesRead));
            if(bytesRead==-1) stderrChannel.close();
        }
        buffer.clear();
        if(stdoutChannel.isOpen()) {
            int bytesRead = stdoutChannel.read(buffer);
            if(bytesRead>0) stdOut.append(new String(buffer.array(),0,bytesRead));
            if(bytesRead==-1) stdoutChannel.close();
        }
        Thread.sleep(100);
    }

    if(stdOut.length()>0) System.out.println("STDOUT: " + stdOut);
    if(stdErr.length()>0) System.out.println("STDERR: " + stdErr);
}