JDK5的ProcessBuilder介绍和使用实例

  原文地址:http://www.java2000.net/p9751
  JDK地址:http://www.java2000.net/doc/jdk6_cn/java/lang/ProcessBuilder.html
  一、JDK中的介绍摘录
  此类用于创建操作系统进程。
  每个ProcessBuilder实例管理一个进程属性集。start()方法利用这些属性创建一个新的Process实例。start()方法可以从同一实例重复调用,以利用相同的或相关的属性创建新的子进程。
  每个进程生成器管理这些进程属性:
  *命令
  是一个字符串列表,它表示要调用的外部程序文件及其参数(如果有)。在此,表示有效的操作系统命令的字符串列表是依赖于系统的。例如,每一个总体变量,通常都要成为此列表中的元素,但有一些操作系统,希望程序能自己标记命令行字符串——在这种系统中,Java实现可能需要命令确切地包含这两个元素。
  *环境
  是从变量到值的依赖于系统的映射。初始值是当前进程环境的一个副本(请参阅System.getenv())。
  *工作目录
  默认值是当前进程的当前工作目录,通常根据系统属性user.dir来命名。
  *redirectErrorStream属性
  最初,此属性为false,意思是子进程的标准输出和错误输出被发送给两个独立的流,这些流可以通过Process.getInputStream()和Process.getErrorStream()方法来访问。如果将值设置为true,标准错误将与标准输出合并。这使得关联错误消息和相应的输出变得更容易。在此情况下,合并的数据可从Process.getInputStream()返回的流读取,而从Process.getErrorStream()返回的流读取将直接到达文件尾。
  修改进程构建器的属性将影响后续由该对象的start()方法启动的进程,但从不会影响以前启动的进程或Java自身的进程。
  大多数错误检查由start()方法执行。可以修改对象的状态,但这样start()将会失败。例如,将命令属性设置为一个空列表将不会抛出异常,除非包含了start()。
  注意,此类不是同步的。如果多个线程同时访问一个ProcessBuilder,而其中至少一个线程从结构上修改了其中一个属性,它必须保持外部同步。
  很容易启动一个使用默认工作目录和环境的新进程:
  Process p=new ProcessBuilder("myCommand","myArg").start();
  下面是一个利用修改过的工作目录和环境启动进程的例子:
  ProcessBuilder pb=new ProcessBuilder("myCommand","myArg1","myArg2");
  Map env=pb.environment();
  env.put("VAR1","myValue");
  env.remove("OTHERVAR");
  env.put("VAR2",env.get("VAR1")+"suffix");
  pb.directory(new File("myDir"));
  Process p=pb.start();
  二、使用案例
  使用Runtime的例子
  package net.java2000.util;
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.Arrays;
  /**
  *
  * author赵学庆,Java世纪网(java2000.net)
  *
  */
  public class TestRuntime{
  /**
  * param args
  * throws Exception
  */
  public static void main(String[]args)throws Exception{
  Runtime runtime=Runtime.getRuntime();
  Process process=runtime.exec("cmd/c dir",null,new File("e:/"));
  InputStream is=process.getInputStream();
  InputStreamReader isr=new InputStreamReader(is,"GBK");
  BufferedReader br=new BufferedReader(isr);
  String line;
  System.out.printf("Output of running%s is:",Arrays.toString(args));
  while((line=br.readLine())!=null){
  System.out.println(line);
  }
  }
  }
  使用ProcessBuilder的例子
  package net.java2000.util;
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.Arrays;
  /**
  *
  * author赵学庆,Java世纪网(java2000.net)
  *
  */
  public class TestProcessBuilder{
  public static void main(String args[])throws Exception{
  ProcessBuilder builder=new ProcessBuilder("cmd","/c","dir");
  builder.directory(new File("e:/"));
  Process process=builder.start();
  InputStream is=process.getInputStream();
  InputStreamReader isr=new InputStreamReader(is,"GBK");
  BufferedReader br=new BufferedReader(isr);
  String line;
  System.out.printf("Output of running%s is:",Arrays.toString(args));
  while((line=br.readLine())!=null){
  System.out.println(line);
  }
  }
  }
  总结:
  ProcessBuilder为进程提供了更多的控制,例如,可以设置当前工作目录,还可以改变环境参数。而Process的功能相对来说简单的多。
  ProcessBuilder是一个final类,有两个带参数的构造方法,你可以通过构造方法来直接创建ProcessBuilder的对象。而Process是一个抽象类,一般都通过Runtime.exec()和ProcessBuilder.start()来间接创建其实例。