学习了两篇的Runtime类,现在对它有了更深一层的了解,那么我们来看看下面的代码:
因为以上代码,我使用了Ubuntu9.10下执行,是一点问题都没有,但当我在windows xp下执行,意外却发生了。
E:classescomjavaworldjpitfallsarticle2>java BadExecWinDir
java.io.IOException: CreateProcess: dir error=2
at java.lang.Win32Process.create(Native Method)
at java.lang.Win32Process.<init>(Unknown Source)
at java.lang.Runtime.execInternal(Native Method)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at BadExecWinDir.main(BadExecWinDir.java:12)
也许大家觉得奇怪,其实我也很奇怪,为什么呢。好好在Linux下,咋到XP就有问题了呢。
以下引用了别人的话:
说实在的,这个错误还真是让我摸不着头脑,我觉得在windows中返回2应该是没有找到这个文件的缘故,可能windows 2000中只有cmd命令,dir命令不是当前环境变量能够解释的吧。我也不知道了,慢慢往下看吧。
嘿,果然和作者想的一样,就是因为dir命令是由windows中的解释器解释的,直接执行dir时无法找到 dir.exe这个命令,所以会出现文件未找到这个2的错误。如果我们要执行这样的命令,就要先根据操作系统的不同执行不同的解释程序 command.com 或者cmd.exe。
到这里,大家明白了吧。
因此,别人还作了一些改进:
因为我在linux下运行,得不到想要的结果。
以下引用作者的话:
这里作者教了一个windows中很有用的方法,呵呵,至少我是不知道的,就是cmd.exe /C +一个windows中注册了后缀的文档名,windows会自动地调用相关的程序来打开这个文档,我试了一下,的确很好用,但是好像文件路径中有空格的 话就有点问题,我加上引号也无法解决。
这里作者强调了一下,不要假设你执行的程序是可执行的程序,要清楚自己的程序是单独可执行的还是被解释的,本章的结束作者会介绍一个命令行工具来帮助我们分析。
这里还有一点,就是得到process的输出的方式是getInputStream,这是因为我们要从Java 程序的角度来看,外部程序的输出对于Java来说就是输入,反之亦然。
最后的一个漏洞的地方就是错误的认为exec方法会接受所有你在命令行或者Shell中输入并接受的字符串。这些错误主要 出现在命令作为参数的情况下,程序员错误的将所有命令行中可以输入的参数命令加入到exec中(这段翻译的不好,凑合看吧)。下面的例子中就是一个程序员 想重定向一个命令的输出。
程序员的本意是将Hello World这个输入重订向到一个文本文件中,但是这个文件并没有生成,jecho仅仅是将命令行中的参数输出到标准输出中,用户觉得可以像dos中重定向 一样将输出重定向到一个文件中,但这并不能实现,用户错误的将exec认为是一个shell解释器,但它并不是,如果你想将一个程序的输出重定向到其他的 程序中,你必须用程序来实现他。可用java.io中的包。
这里就不多说了,看看就明白,紧接着作者给出了一个监测命令的小程序
193在windows中是说这不是一个win32程序,这说明路径中找不到这个网页的关联程序,下面作者决定用一个绝对路径来试一下。
E:classescomjavaworldjpitfallsarticle2>java TestExec
"e:program filesnetscapeprogramnetscape.exe e:javadocsindex.html"
ExitValue: 0
好用了,这个我也试了一下,用的是IE。
最后,作者总结了几条规则,防止我们在进行Runtime.exec()调用时出现错误。
在一个外部进程执行完之前你不能得到他的退出状态
在你的外部程序开始执行的时候你必须马上控制输入、输出、出错这些流。
你必须用Runtime.exec()去执行程序
你不能象命令行一样使用Runtime.exec()。
以上引用了很多别人的例子同原文。