- 浏览: 100878 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
kingcs:
IndexSearcher 没有关闭。 searcher.cl ...
lucene第一步---6.分页 -
xyheritrix:
看了后我没一点点刺激,你的3个例子对我根本说明不了问题,在我看 ...
从优秀迈向卓越 -- 我的设计模式学习感悟 -
zl0828:
这个小知识值得分享,我支持lz分享
jquery ui 1.7版中的datepicker大小問題
学习了两篇的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()。
以上引用了很多别人的例子同原文。
import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader ; import java.io.BufferedReader; public class Exec_Output{ public static void main(String []args)throws IOException,InterruptedException{ Runtime rt = Runtime.getRuntime(); Process p = rt.exec("dir"); //int exitValue = p.exitValue(); //int exitValue = p.waitFor(); InputStream is = p.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; System.out.println("<OUTPUT>"); while((line = br.readLine())!=null){ System.out.println(line); System.out.println("</OUTPUT>"); int exitValue = p.waitFor(); System.out.println("Process exitValue="+exitValue); } } } //执行结果(在Ubuntu9.10下执行) <OUTPUT> class CUtil.java Exec.java Exec_Javac.java Exec_Output.java Str.java </OUTPUT>
因为以上代码,我使用了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。
到这里,大家明白了吧。
因此,别人还作了一些改进:
import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader ; import java.io.BufferedReader; public class Exec_Output_Win{ public static void main(String []args)throws IOException,InterruptedException{ if(args.length < 1){ System.out.println("USAGE:java Exec_Output_Win <cmd>"); System.exit(1); } try{ String osName = System.getProperty("os.name"); String []cmd = new String[3]; if(osName.equals("Windows NT")){ cmd[0] = "cmd.exe"; cmd[1] = "/C"; cmd[2] = args[0]; }else if(osName.equals("Windows 95")){ cmd[0] = "command.com"; cmd[1] = "/C"; cmd[2] = args[0]; }else if(osName.equals("Linux")){ System.out.println("Os:"+osName); System.exit(0); } Runtime rt = Runtime.getRuntime(); System.out.println("Execing "+cmd[0]+" "+cmd[1]+" "+cmd[2]); Process p = rt.exec(cmd); //any error message? StreamGobbler err = new StreamGobbler(p.getErrorStream(),"ERROR"); //any output? StreamGobbler out= new StreamGobbler(p.getInputStream(),"OUTPUT"); //kick them off err.start(); out.start(); //any error? int exitValue = p.waitFor(); System.out.println("Process exitValue="+exitValue); }catch(Exception e){ e.printStackTrace(); } } } class StreamGobbler extends Thread{ InputStream is; String type; StreamGobbler(InputStream is,String type){ this.is = is; this.type = type; } public void run(){ try{ InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; while((line = br.readLine())!=null){ System.out.println(type +">"+line); } }catch(IOException e){ e.printStackTrace(); } } } //执行结果: (Linux 环境下) Os:Linux (windows XP环境下) E:classescomjavaworldjpitfallsarticle2>java GoodWindowsExec "dir *.java" Execing cmd.exe /C dir *.java OUTPUT> Volume in drive E has no label. OUTPUT> Volume Serial Number is 5C5F-0CC9 OUTPUT> OUTPUT> Directory of E:classescomjavaworldjpitfallsarticle2 OUTPUT> OUTPUT>10/23/00 09:01p 805 BadExecBrowser.java OUTPUT>10/22/00 09:35a 770 BadExecBrowser1.java OUTPUT>10/24/00 08:45p 488 BadExecJavac.java OUTPUT>10/24/00 08:46p 519 BadExecJavac2.java OUTPUT>10/24/00 09:13p 930 BadExecWinDir.java OUTPUT>10/22/00 09:21a 2,282 BadURLPost.java OUTPUT>10/22/00 09:20a 2,273 BadURLPost1.java ... (some output omitted for brevity) OUTPUT>10/12/00 09:29p 151 SuperFrame.java OUTPUT>10/24/00 09:23p 1,814 TestExec.java OUTPUT>10/09/00 05:47p 23,543 TestStringReplace.java OUTPUT>10/12/00 08:55p 228 TopLevel.java OUTPUT> 22 File(s) 46,661 bytes OUTPUT> 19,678,420,992 bytes free ExitValue: 0
因为我在linux下运行,得不到想要的结果。
以下引用作者的话:
这里作者教了一个windows中很有用的方法,呵呵,至少我是不知道的,就是cmd.exe /C +一个windows中注册了后缀的文档名,windows会自动地调用相关的程序来打开这个文档,我试了一下,的确很好用,但是好像文件路径中有空格的话就有点问题,我加上引号也无法解决。
这里作者强调了一下,不要假设你执行的程序是可执行的程序,要清楚自己的程序是单独可执行的还是被解释的,本章的结束作者会介绍一个命令行工具来帮助我们分析。
这里还有一点,就是得到process的输出的方式是getInputStream,这是因为我们要从Java 程序的角度来看,外部程序的输出对于Java来说就是输入,反之亦然。
最后的一个漏洞的地方就是错误的认为exec方法会接受所有你在命令行或者Shell中输入并接受的字符串。这些错误主要出现在命令作为参数的情况下,程序员错误的将所有命令行中可以输入的参数命令加入到exec中(这段翻译的不好,凑合看吧)。下面的例子中就是一个程序员想重定向一个命令的输出。
import java.util.*; import java.io.*; // StreamGobbler omitted for brevity public class BadWinRedirect { public static void main(String args[]) { try { Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("java jecho 'Hello World' > test.txt"); // any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR"); // any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT"); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } Running BadWinRedirect produces: E:classescomjavaworldjpitfallsarticle2>java BadWinRedirect OUTPUT>'Hello World' > test.txt ExitValue: 0
程序员的本意是将Hello World这个输入重订向到一个文本文件中,但是这个文件并没有生成,jecho仅仅是将命令行中的参数输出到标准输出中,用户觉得可以像dos中重定向一样将输出重定向到一个文件中,但这并不能实现,用户错误的将exec认为是一个shell解释器,但它并不是,如果你想将一个程序的输出重定向到其他的程序中,你必须用程序来实现他。可用java.io中的包。
import java.util.*; import java.io.*; class StreamGobbler extends Thread { InputStream is; String type; OutputStream os; StreamGobbler(InputStream is, String type) { this(is, type, null); } StreamGobbler(InputStream is, String type, OutputStream redirect) { this.is = is; this.type = type; this.os = redirect; } public void run() { try { PrintWriter pw = null; if (os != null) pw = new PrintWriter(os); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line=null; while ( (line = br.readLine()) != null) { if (pw != null) pw.println(line); System.out.println(type + ">" + line); } if (pw != null) pw.flush(); } catch (IOException ioe) { ioe.printStackTrace(); } } } public class GoodWinRedirect { public static void main(String args[]) { if (args.length < 1) { System.out.println("USAGE java GoodWinRedirect <outputfile>"); System.exit(1); } try { FileOutputStream fos = new FileOutputStream(args[0]); Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("java jecho 'Hello World'"); // any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR"); // any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT", fos); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); fos.flush(); fos.close(); } catch (Throwable t) { t.printStackTrace(); } } } Running GoodWinRedirect produces: E:classescomjavaworldjpitfallsarticle2>java GoodWinRedirect test.txt OUTPUT>'Hello World' ExitValue: 0
这里就不多说了,看看就明白,紧接着作者给出了一个监测命令的小程序
import java.util.*; import java.io.*; // class StreamGobbler omitted for brevity public class TestExec { public static void main(String args[]) { if (args.length < 1) { System.out.println("USAGE: java TestExec "cmd""); System.exit(1); } try { String cmd = args[0]; Runtime rt = Runtime.getRuntime(); Process proc = rt.exec(cmd); // any error message? StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERR"); // any output? StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUT"); // kick them off errorGobbler.start(); outputGobbler.start(); // any error??? int exitVal = proc.waitFor(); System.out.println("ExitValue: " + exitVal); } catch (Throwable t) { t.printStackTrace(); } } } //对这个程序进行运行: E:classescomjavaworldjpitfallsarticle2>java TestExec "e:javadocsindex.html" java.io.IOException: CreateProcess: e:javadocsindex.html error=193 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 TestExec.main(TestExec.java:45)
193在windows中是说这不是一个win32程序,这说明路径中找不到这个网页的关联程序,下面作者决定用一个绝对路径来试一下。
E:classescomjavaworldjpitfallsarticle2>java TestExec
"e:program filesnetscapeprogramnetscape.exe e:javadocsindex.html"
ExitValue: 0
好用了,这个我也试了一下,用的是IE。
最后,作者总结了几条规则,防止我们在进行Runtime.exec()调用时出现错误。
在一个外部进程执行完之前你不能得到他的退出状态
在你的外部程序开始执行的时候你必须马上控制输入、输出、出错这些流。
你必须用Runtime.exec()去执行程序
你不能象命令行一样使用Runtime.exec()。
以上引用了很多别人的例子同原文。
发表评论
-
Tomcat6源码分析
2011-04-19 12:20 997作为一位Java程序员,如果您没有接触过开源软件、项目或框架的 ... -
Java程序打包成Jar包
2011-04-18 00:38 1119例如有如下窗体程序, ... -
【解惑】深入jar包:从jar包中读取资源文件
2011-04-18 00:34 665我们常常在代码中读取 ... -
【解惑】深入jar包:从jar包中读取资源文件
2011-04-18 00:34 714我们常常在代码中读取 ... -
Java Tips: 将Exception的stacktrace信息转成字符串
2011-03-25 15:11 860StringWriter sw = new StringWri ... -
JAVABean 排序
2011-03-03 18:00 2486众所周知,如果需要在 Java 中使用排序方法,那么就需要实现 ... -
Java调用系统命令学习(二)
2011-03-01 11:09 753经过上一篇的学习,应 ... -
Java调用系统命令学习(一)
2011-03-01 11:07 684import java.io.*; class Exec{ ... -
Java HashMap和TreeMap的排序问题总结
2011-02-17 10:26 1419Map存储的是key->value的值对,key的值是唯 ... -
为什么要用new String(str.getBytes("iso-8859-1"),"GBK")
2010-11-03 09:58 1632比如汉字“我”,假设它的值是22530(只是假设,具体多少我没 ... -
Daemon thread
2010-11-02 13:37 10791.所谓守护线程就是运行在程序后台的线程,程序的主线程Main ... -
告别获取不安全的相对路径-取当前类的Classpath
2010-10-20 10:56 736这是一个古老的话题了, ...
相关推荐
### Java调用Linux命令 Java提供了一种强大的机制来执行操作系统级别的任务,其中包括调用Linux命令。实现这一功能的核心是`Runtime`类中的`exec()`方法。这个方法允许Java应用程序创建一个新的进程来执行指定的...
在Java编程中,有时候我们需要执行一些操作系统级别的任务,例如启动一个外部程序、执行一些系统命令等。这通常可以通过Java的`Runtime`类实现,尤其是通过`Runtime.exec()`方法来创建一个新的进程。本文将详细介绍...
标题 "perl脚本调用练习和调用系统命令并展示输出信息" 提示我们这篇内容主要涉及使用Perl脚本执行系统命令以及如何处理输出信息。Perl是一种强大的文本处理语言,常用于系统管理任务,包括调用其他系统工具或程序。...
Java提供了`Runtime.getRuntime().exec()`方法或`ProcessBuilder`类来执行系统命令。例如,我们可以使用以下Java代码来执行一个简单的FFmpeg命令: ```java String command = "ffmpeg -i input.mp4 output.mp4"; ...
Java调用SPSS的实例是将Java编程语言与统计分析软件SPSS(Statistical Product and Service Solutions)结合使用的典型应用。SPSS提供了Java接口,使得开发者可以利用Java代码执行SPSS的数据处理和分析任务,无需...
标题 "exchange/powershell,Java调用powershell开通邮箱" 暗示了这是一个关于使用Java编程语言调用PowerShell脚本在Exchange服务器上创建邮箱的教程或项目。Exchange是微软提供的一款企业级电子邮件服务器软件,而...
在Java中调用FFmpeg,通常有两种方式:直接执行系统命令和使用Java库。直接执行命令是通过Runtime.exec()方法或ProcessBuilder类来调用FFmpeg的命令行工具,例如: ```java String command = "ffmpeg -i input.mp4 ...
3. **Rscript**: Java可以通过`Runtime.getRuntime().exec()`方法执行系统命令,调用R脚本并捕获输出。这种方法简单,但不适合复杂的交互式任务,因为每次调用都会启动新的R进程。 4. **rJava**: rJava是R的一个...
Java调用SPSS实例主要涉及的是如何通过编程方式与SPSS进行交互,这在数据分析、自动化报告或构建数据处理系统时非常有用。SPSS(Statistical Product and Service Solutions)是一款强大的统计分析软件,而它的Java...
Java调用本地浏览器的示例,通常涉及到Java与操作系统交互的能力,这主要通过Java的`Runtime`类或者`ProcessBuilder`类实现。这两个类允许Java程序执行系统命令,例如打开一个本地已安装的浏览器来加载特定的URL。...
通过本文的学习,我们了解到了如何在Java中调用本地exe文件的基本原理、常见应用场景以及具体的代码实现细节。掌握这些技能对于开发人员来说是非常有用的,可以帮助我们更好地利用Java与操作系统之间的交互能力。
Java调用C++ DLL文件是跨语言编程中的一个重要应用场景,特别是在既有Java代码库又有C++动态链接库的情况下。本文将详细讲解如何在Java程序中调用C++编写的DLL文件,以及一个可用的示例。 首先,理解Java与C++交互...
例如,"Java调用Python脚本"是一个常见的需求,特别是在数据处理、科学计算或机器学习等场景中,Python的强大库可以与Java的稳定性和企业级应用能力相结合。本教程将详细讲解如何在Java程序中调用Python脚本。 首先...
在Java编程中,有时我们需要与操作系统进行交互,执行一些系统级别的任务,比如调用Shell脚本。这在处理自动化任务、远程服务器管理或系统集成时非常常见。在给定的资源中,我们可以看到如何在Java中实现这个功能,...
这是原生 Java 提供的方法,通过执行系统命令来运行 Python 脚本。例如,你可以创建一个 `ProcessBuilder` 实例,指定 Python 解释器和脚本路径,然后启动进程。这种方法简单,但效率较低,且不适用于复杂的交互式...
在Mac环境下,使用Java调用OpenCV库是一个常见的需求,特别是在计算机视觉和图像处理的项目中。OpenCV是一个强大的开源库,提供了丰富的功能,用于图像处理、计算机视觉算法以及机器学习。本文将详细介绍如何在Mac上...
6. **环境搭建**:配合"windows下java调用ffmpeg视频处理环境搭建",这部分可能包括如何在Windows系统上安装FFmpeg,设置环境变量,以及如何确保Java程序能正确找到并执行FFmpeg的可执行文件。 7. **错误处理和日志...
这两个类提供了运行外部进程的能力,从而允许Java程序调用系统命令。 在给定的描述中,虽然没有提供具体的信息,但我们可以推测这篇博文可能是博主Qindongliang分享的一个实用工具,可能包括如何在Java代码中构建和...
Java中的`Runtime.getRuntime().exec()`方法允许我们执行系统命令,这就为我们提供了与Mplayer交互的途径。通过构建命令字符串,我们可以启动Mplayer、传递参数(如文件路径)以及执行播放控制操作。 1. **进程管理...