Runtime.getRuntime().exec()需要注意的地方

文章出处http://www.cnblogs.com/fclbky/p/6112180.html

有时候我们可能需要调用系统外部的某个程序,此时就可以用Runtime.getRuntime().exec()来调用,他会生成一个新的进程去运行调用的程序。

此方法返回一个java.lang.Process对象,该对象可以得到之前开启的进程的运行结果,还可以操作进程的输入输出流。

Process对象有以下几个方法:

  1、destroy()      杀死这个子进程

  2、exitValue()      得到进程运行结束后的返回状态

  3、waitFor()       得到进程运行结束后的返回状态,如果进程未运行完毕则等待知道执行完毕

  4、getInputStream()  得到进程的标准输出信息流

  5、getErrorStream()  得到进程的错误输出信息流

  6、getOutputStream() 得到进程的输入流

现在来讲讲exitValue(),当线程没有执行完毕时调用此方法会跑出IllegalThreadStateException异常,最直接的解决方法就是用waitFor()方法代替。

但是waitFor()方法也有很明显的弊端,因为java程序给进程的输出流分配的缓冲区是很小的,有时候当进程输出信息很大的时候回导致缓冲区被填满,如果不及时处理程序会阻塞。如果程序没有对进程的输出流处理的会就会导致执行exec()的线程永远阻塞,进程也不会执行下去直到输出流被处理或者java程序结束。

解决的方法就是处理缓冲区中的信息,开两个线程分别去处理标准输出流和错误输出流。

程序如下:

public class ExecTest {

    public static void main(String[] args) throws IOException, InterruptedException {
      String cmd = "cmd /c dir c:\\windows";
      final Process process = Runtime.getRuntime().exec(cmd);
      printMessage(process.getInputStream());
      printMessage(process.getErrorStream());
      int value = process.waitFor();
      System.out.println(value);
    }

    private static void printMessage(final InputStream input) {
      new Thread(new Runnable() {
         public void run() {
            Reader reader = new InputStreamReader(input);
            BufferedReader bf = new BufferedReader(reader);
            String line = null;
             try {
                while((line=bf.readLine())!=null) {
                    System.out.println(line);
                }
             } catch (IOException e) {
                e.printStackTrace();
             }
         }
      }).start();
    }
}

如上程序,读取进程的输出信息并打印到控制台就不会发生阻塞,程序能正常的结束。

tips:

  cmd命令不能需要加上cmd /c才能执行,不然java会去path中找dir.exe

  在windows一般字符集编码为GBK,需要在转换成Reader的时候指定为GBK编码.

时间: 2024-10-09 17:11:35

Runtime.getRuntime().exec()需要注意的地方的相关文章

用Runtime.getRuntime().exec()需要注意的地方

d有时候我们可能需要调用系统外部的某个程序,此时就可以用Runtime.getRuntime().exec()来调用,他会生成一个新的进程去运行调用的程序. 此方法返回一个java.lang.Process对象,该对象可以得到之前开启的进程的运行结果,还可以操作进程的输入输出流. Process对象有以下几个方法: 1.destroy() 杀死这个子进程 2.exitValue() 得到进程运行结束后的返回状态 3.waitFor() 得到进程运行结束后的返回状态,如果进程未运行完毕则等待知道执

Runtime.getRuntime.exec()执行linux脚本导致程序卡死有关问题

Runtime.getRuntime.exec()执行linux脚本导致程序卡死问题问题: 在Java程序中,通过Runtime.getRuntime().exec()执行一个Linux脚本导致程序被挂住,而在终端上直接执行这个脚本则没有任何问题.原因: 先来看Java代码: public final static void process1(String[] cmdarray) {        Process p = null;        BufferedReader br = null

Runtime.getRuntime().exec()调用外部程序

场景:linux下,在web工程里调用一个C++程序,实现代码如下: StringBuffer cmd = new StringBuffer();cmd.append("nohup "); ……System.out.println("执行程序命令:"+cmd.toString());String[] cmds = { "/bin/sh", "-c", cmd.toString()};Runtime.getRuntime().e

Android ProcessBuilder与Runtime.getRuntime().exec分别创建进程的区别

在Android中想要进行Ping,在不Root机器的情况下似乎还只能进行底层命调用才能实现. 因为在Java中要进行ICMP包发送需要Root权限. 于是只能通过创建进程来解决了,创建进程在Java中有两种方式,分别为: 1. 调用ProcessBuilder的构造函数后执行start() 2. 用Runtime.getRuntime().exec()方法执行 经过使用后发现两者有区别但是也并不是很大,两个例子说明: 1.调用ProcessBuilder的构造函数后执行start(): Pro

Java Runtime.getRuntime().exec 执行带空格命令解决办法

String command = OpenOffice_HOME + "program\\soffice -headless -accept=\"socket,host=127.0.0.1,port=8100;urp;\" -nofirststartwizard "; command = "cmd /c start "+command.replaceAll(" ","\" \""); P

Runtime.getRuntime().exec方法

Runtime.getRuntime().exec共有四个重载方法: public Process exec(String command) 在单独的进程中执行指定的字符串命令. public Process exec(String [] cmdArray) 在单独的进程中执行指定命令和变量 public Process exec(String command, String [] envp) 在指定环境的独立进程中执行指定命令和变量 public Process exec(String []

Eclipse下使用Runtime.getRuntime().exec启动ja

window7系统下实验(linux下路径格式和windows下不一样) Eclipse下使用Runtime.getRuntime().exec启动ja RunTime.getRuntime().exec("java My_Program");System.exit(0); which would start a whole new JVM running your program, and then kill the original. Not exactly pretty or e

Android平台 Runtime.getRuntime().exec

import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; public class RootCmd { private static boolean mHaveRoot = false; public static boolean haveRoot() { if (!mHaveRoot) { int ret = execRootCmdSilent("echo test&

Runtime.getRuntime().exec()----记录日志案例

Runtime.getRuntime().exec()方法主要用于执行外部的程序或命令. Runtime.getRuntime().exec共有六个重载方法: 1.public Process exec(String command) 在单独的进程中执行指定的字符串命令. 2.public Process exec(String [] cmdArray) 在单独的进程中执行指定命令和变量 3.public Process exec(String command, String [] envp)