现在的位置: 首页 > 综合 > 正文

浅析Java执行外部命令的几个要点(1)——简单的使用范例以及在Cygwin上的注意点

2018年05月25日 ⁄ 综合 ⁄ 共 2335字 ⁄ 字号 评论关闭

转贴请注明出处:http://blog.csdn.net/froole
作者:郝春利

在Java语言中执行外部命令,到JDK1.4,一直都是使用java.lang.Runtime。从JDK1.5版本之后导入了java.lang.ProcessBuilder,并且是用起来同样非常方便。
java.lang.Runtime的例子在网上已经太多,这里不做重复,举一个java.lang.ProcessBuilder的范例,并简单说明几个要点。

1.Runtime VS ProcessBuilder
跟Runtime相比,ProcessBuilder有个特点,被执行的命令可以同ProcessBuilder一起被初始化。
例如事先定一一个启动文本编辑器的命令,可以如下:
new ProcessBuilder("notepad.exe", "test.txt");
Runtime是直接运行exeuct,所以,如果要需要执行的命令是不变的,使用ProcessBuilder对命令进行初始化,这要比使用Runtime更加方便,而且,从某种角度说,正确使用ProcessBuilder可以避免一些生成外部命令时容易发生的错误。
但是,需要注意的事,老版本和新版本的功能是没有变化的,具体用哪个,还需要具体情况具体分析。
以下是一个使用ProcessBuilder的例子:

  1.  ProcessBuilder pb = new ProcessBuilder("notepad.exe""test.txt");
  2.  try {
  3.  Process p = pb.start();
  4.  int ret = p.waitFor();
  5.  System.out.println("process exited with value : " + ret);
  6.  } catch (IOException e) {
  7.  // start()命令的执行处理失败
  8.     e.printStackTrace();
  9.  } catch (InterruptedException e) {
  10.  // waitFor()处理失败
  11.     e.printStackTrace();
  12.  }



2.外部程序执行之后,提取执行结果
无论使用Runtime.exeuc还是ProcessBuilder.start执行外部命令,都会返回一个Process实现。
外部命令执行后,向OS输出的所有返回结果都可以通过Process来取得。其中,用来表示命令执行结束状态的出口值,可以通过调用exitValue()或者waitFor()方法来提取。
但是exitValue()跟waitFor()有一个本质区别,调用waitFor()之后,程序并不会马上返回出口状态,而是一直等到外部程序执行结束,调用exitValue(),如果子程序没有结束,就会抛出一个IllegalThreadStateException异常
所以,在大多数情况下,通过调用waitFor()来取得外部程序的执行结果更加安全。
waitFor()的确是好,但是有时候却事与愿违。
例如,外部程序的执行时间超出了预定的执行时间(Timeout);外部程序可以正常执行,但是,在Java执行就无缘无故停在半路不动了。
在实际的外部程序运行中将会出现很多状况,《浅析Java执行外部命令的几个要点》将在今后的部分中作具体的介绍。

3.在Cygwin上使用Sun JVM最需要注意的地方
Cygwin是一款跑在Windows上的Unix虚拟软件。
Cygwin上默认Unix格式的文件路径,例如:/usr/bin/find,当然,C:/WINDOWS这样的路径也可以使用。
虽然Cygwin是虚拟的Unix环境,但是,里面的命令归根结底还是Win32内核下的执行程序,所以Cygwin上可以执行Windows下的命令。
这就给在Cygwin下执行Java程序的混乱带来了隐患,因为,Cygwin下,默认Unix路径,而在Cygwin下执行的Java是在Windows上的JVM。
现象及解决方法:

  • 要在Cygwin下,把/home/xx这个路径传给Java程序,Java得到这个路径之后,将会默认为[系统盘:/home/xx],可是,实际这个
    [/home/xx]是在[$Cygwin/home/xx],这个时候,就出现了混乱,Java无法找到所指定的路径在什么地方。这种情况的解决方法,就是把/home/xx这个路径,用Windows上的绝对路径替代,如:[C:/Cygwinpath/home/xx]
  • Java下无法认出Windows文件系统的路径分隔符。当然,这个问题在DOS下同样存在。

    如在Cygwin下执行/usr/bin/find命令,并将输出结果通过xargs传给Java程序,这个时候Java程序会报错,找不到所指定的路
    径。原因是被带入到Java中的路径格式如[C:/WINDOWS/xxx]中,“/”在Java中的字串变量中,是默认的escape字符,也就是说,
    传给Java的是[C:/WINDOWS/xxx],到了Java里面[C:WINDOWSxxx]。
    很多系统都是在Windows下开发,Unix下运用,特别是后台程序,如果遇到处理文件系统路径的问题,需特别注意这一点。如果程序最终在Unix下运行,测试的时候,不妨把路径中的“/”改成“/”,如果实在不行,就只能拿到Unix下去测试。

相关:
-浅析Java执行外部命令的几个要点(1)
-浅析Java执行外部命令的几个要点(2)
-浅析Java执行外部命令的几个要点(3)
-浅析Java执行外部命令的几个要点(4)


转贴请注明出处:http://blog.csdn.net/froole

抱歉!评论已关闭.