使用Java调用系统程序

一、概述

Runtime类

Runtime类封装了运行时的环境。

每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。

一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用。

一旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控制Java虚拟机的状态和行为。

Process类

Process类是一个抽象类(所有的方法均是抽象的),封装了一个进程(即一个执行程序)。

Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。 ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获取相关信息。

创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin,stdout,stderr)操作都将通过三个流 (getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。

ProcessBuilder类

ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。在J2SE 1.5之前,都是由Process类处来实现进程的控制管理。

每个 ProcessBuilder 实例管理一个进程属性集。它的start() 方法利用这些属性创建一个新的 Process 实例。start() 方法可以从同一实例重复调用,以利用相同的或相关的属性创建新的子进程。

ProcessBuilder为进程提供了更多的控制,例如,可以设置当前工作目录,还可以改变环境参数。而Process的功能相对来说简单的多。
       ProcessBuilder是一个final类,有两个带参数的构造方法,你可以通过构造方法来直接创建ProcessBuilder的对象。而Process是一个抽象类,一般都通过Runtime.exec()和ProcessBuilder.start()来间接创建其实例。

注意: 

修改进程构建器的属性将影响后续由该对象的 start() 方法启动的进程,但从不会影响以前启动的进程或 Java 自身的进程。
      ProcessBuilder类不是同步的。如果多个线程同时访问一个 ProcessBuilder,而其中至少一个线程从结构上修改了其中一个属性,它必须 保持外部同步。

二、常见应用  

1.获取RunTime信息

/**
 * 获取runTime信息
 */
public static void GetRuntimeInfo(Runtime runtime) {
    // 返回 Java 虚拟机试图使用的最大内存量,默认是系统的1/4
    System.out.println("最大内存:" + runtime.maxMemory());
    // 返回 Java 虚拟机中的内存总量,默认是系统的1/64
    System.out.println("内存总量:" + runtime.totalMemory());
    // 返回 Java 虚拟机中的空闲内存量
    System.out.println("空闲内存:" + runtime.freeMemory());
    // 向 Java 虚拟机返回可用处理器的数目
    System.out.println("可用CPU数:" + runtime.availableProcessors());
}

例:GetRuntimeInfo(runtime); runtime.gc(); GetRuntimeInfo(runtime);观察打印信息的变化。

2.执行命令(在独立的进程中)

/**
 * 执行命令调用程序
 */
public static void executeCmd(String strCmd) {
    Runtime runtime = Runtime.getRuntime();
    try {
        runtime.exec(strCmd);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

例:executeCmd("notepad.exe"); 打开系统记事本。

3.获取子进程结束时的返回值

Runtime r = Runtime.getRuntime();
Process p = null;
try{
    p = r.exec("notepad");
    p.waitFor(); // 等待子进程结束
} catch (Exception e) {
    System.out.println("Error executing notepad.");
}
System.out.println("Notepad returned " + p.exitValue()); // 子进程返回值

4.

ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("ping","127.0.0.1");
//将标准输入流和错误输入流合并,通过标准输入流读取信息
processBuilder.redirectErrorStream(true);
try {
    //启动进程
    Process process = processBuilder.start();
    //获取输入流
    InputStream inputStream = process.getInputStream();
    //转成字符输入流
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
    int len = -1;
    char[] c = new char[1024];
    StringBuffer outputString = new StringBuffer();
    //读取进程输入流中的内容
    while ((len = inputStreamReader.read(c)) != -1) {
        String s = new String(c, 0, len);
        outputString.append(s);
        System.out.print(s);
    }
    inputStream.close();
} catch (IOException e) {
    e.printStackTrace();
}

5.更多使用方法查看官方API

 

参考:

发布了19 篇原创文章 · 获赞 9 · 访问量 2999

猜你喜欢

转载自blog.csdn.net/Necrolic/article/details/105431040