【问题标题】:Give input command and Get Command Prompt complete Output to textarea In Java给出输入命令并获取命令提示符完成输出到 Java 中的 textarea
【发布时间】:2014-01-06 01:50:38
【问题描述】:

我无法读取程序的完整输出,有时它会挂起界面并且无法完全编译。 在 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);
        }

【问题讨论】:

  • 您的问题是您的长时间运行的进程阻塞了 Swing 事件线程的线程问题。搜索 Swing 和线程。这是一个常见问题,您找到的结果将直接适用于您的问题。
  • 能否请你给我一些相关的阅读或这段代码中的问题。
  • 如果我正确理解了这个问题,它很像我在这个线程中发现的:stackoverflow.com/questions/20600721/… Trashgod 提供了一个很好的例子来说明如何正确地做到这一点。同样,这是假设我正确理解您的问题

标签: java cmd command execute prompt


【解决方案1】:

我看到的问题是这样的。您正在尝试执行一个程序,但在程序完成执行之前,您不会从程序的输出流(即 Process 的 getInputStream())中读取数据。因此,如果您的 subProcess 恰好有很多输出并且耗尽了缓冲区,那么 subProcess 将被阻塞。

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

java.lang.Process 上的 Java 文档说

由于部分原生平台只为标准输入输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取输出流可能会导致子进程阻塞,甚至死锁。

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);
}

【讨论】:

  • 我做了一个快速测试代码供你参考。我选择了非阻塞 IO (NIO),这样您就可以在现有线程中完成所有事情(也可能不是最佳选择 :-))。这段代码展示了如何将输入和错误流读入缓冲区,然后打印出整个内容。
  • 它对于小输出工作正常,但对于大输出程序仍然无法正常工作。输出大约 1000 字。
  • 我已经编辑了测试程序,通过休眠 100 毫秒而不是 1000 毫秒来更快地读取数据。我还使用了 buffer.clear() 而不是 buffer.rewind()。
  • stackoverflow.com/questions/20600721/… ---这个问题的答案工作正常,但我试图将它与我在 netbeans jform 文件中的程序对按钮事件进行匹配。 ://
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多