`
geshenyi
  • 浏览: 98210 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Java调用系统命令学习(二)

    博客分类:
  • J2SE
阅读更多
经过上一篇的学习,应该对Java中的Runtime类的exec方法了大致的了解,也知道应该如何去使用了吧。

首先学习下:Process类。

简单地测试一下:

调用Javac命令,并查看执行命令的返回值,并输出到控制台上去。
import java.io.IOException;
class Exec_Javac{
        public static void main(String []args)throws IOException{
                Runtime rt = Runtime.getRuntime();
                Process p = rt.exec("javac");
                int exitValue = p.exitValue();
                System.out.println("Process exitValue="+exitValue);
        }
}
//执行结果:
Exception in thread "main" java.lang.IllegalThreadStateException: process hasn't exited
    at java.lang.UNIXProcess.exitValue(UNIXProcess.java:172)
    at Exec_Javac.main(Exec_Javac.java:6)


呵呵,从上面,我们可以知道,并不能得到我们想要的结果。至于什么原因呢。

下面一段话直接引用别人的:(它比较详细地讲述了出错的原因)

这里主要的问题就是错误的调用了exitValue来取得外部命令的返回值(呵呵,这个错误我也曾经犯过),因为 exitValue这个方法是不阻塞的,程序在调用这个方法时外部命令并没有返回所以造成了异常的出现,这里是由另外的方法来等待外部命令执行完毕的,就是waitFor方法,这个方法会一直阻塞直到外部命令执行结束,然后返回外部命令执行的结果,作者在这里一顿批评设计者的思路有问题,呵呵,反正我是无所谓阿,能用就可以拉。但是作者在这里有一个说明,就是exitValue也是有好多用途的。因为当你在一个Process上调用waitFor方法时,当前线程是阻塞的,如果外部命令无法执行结束,那么你的线程就会一直阻塞下去,这种意外会影响我们程序的执行。所以在我们不能判断外部命令什么时候执行完毕而我们的程序还需要继续执行的情况下,我们就应该循环的使用exitValue来取得外部命令的返回状态,并在外部命令返回时作出相应的处理。

那么好,既然出错了,当然要修改啦:

改为如下:
import java.io.IOException;
class Exec_Javac{
        public static void main(String []args)throws IOException,InterruptedException{
                Runtime rt = Runtime.getRuntime();
                Process p = rt.exec("javac");
                //int exitValue = p.exitValue();
                int exitValue = p.waitFor();
                System.out.println("Process exitValue="+exitValue);
        }
}
//执行结果为
Process exitValue=2 

得到上面这个结果是我意想不到的。因为在Windows下执行,会一直阻塞在那里。

却我在Ubuntu里面执行时,却在编译时却却不过,

抛出了这样的异常:

Exec_Javac.java:7: unreported exception java.lang.InterruptedException; must be caught or declared to be thrown
        int exitValue = p.waitFor();
                                 ^
1 error

后来加上InterrupedException才可以执行。可以是环境上的不同。虽然是输出了结果,但是因为异常中断才输出的结果。也不是我想要的结果。这个又是为什么呢?

以下又是引用别人的话:

JDK文档中对此有如此的解释:因为本地的系统对标准输入和输出所提供的缓冲池有效,所以错误的对标准输出快速的写入和从标准输入快速的读入都有可能造成子进程的锁,甚至死锁。


文档引述完了,作者又开始批评了,他说JDK仅仅说明为什么问题会发生,却并没有说明这个问题怎么解决,这的确是个问题哈。紧接着作者说出自己的做法,就是在执行完外部命令后我们要控制好Process的所有输入和输出(视情况而定),在这个例子里边因为调用的是 Javac,而他在没有参数的情况下会将提示信息输出到标准出错,所以在下面的程序中我们要对此进行处理。

呵呵。。不是想要的结果。当然还是得改进啦。

代码如下:
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader ;
import java.io.BufferedReader;
class Exec_Javac{
        public static void main(String []args)throws IOException,InterruptedException{
                Runtime rt = Runtime.getRuntime();
                Process p = rt.exec("javac");
                //int exitValue = p.exitValue();
                //int exitValue = p.waitFor();
                InputStream is = p.getErrorStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                System.out.println("<ERROR>");
                while((line = br.readLine())!=null){
                        System.out.println(line);
                        System.out.println("</ERROR>");
                        int exitValue = p.waitFor();
                        System.out.println("Process exitValue="+exitValue);
                }
        }
}
//执行结果:
<ERROR>
Usage: javac <options> <source files>
</ERROR>
Process exitValue=2
where possible options include:
</ERROR>
Process exitValue=2
  -g                         Generate all debugging info
</ERROR>
Process exitValue=2
  -g:none                    Generate no debugging info
</ERROR>
Process exitValue=2
  -g:{lines,vars,source}     Generate only some debugging info
</ERROR>
Process exitValue=2
  -nowarn                    Generate no warnings
</ERROR>
Process exitValue=2
  -verbose                   Output messages about what the compiler is doing
</ERROR>
Process exitValue=2
  -deprecation               Output source locations where deprecated APIs are used
</ERROR>
Process exitValue=2
  -classpath <path>          Specify where to find user class files and annotation processors
</ERROR>
Process exitValue=2
  -cp <path>                 Specify where to find user class files and annotation processors
</ERROR>
Process exitValue=2
  -sourcepath <path>         Specify where to find input source files
</ERROR>
Process exitValue=2
  -bootclasspath <path>      Override location of bootstrap class files
</ERROR>
Process exitValue=2
  -extdirs <dirs>            Override location of installed extensions
</ERROR>
Process exitValue=2
  -endorseddirs <dirs>       Override location of endorsed standards path
</ERROR>
Process exitValue=2
  -proc:{none,only}          Control whether annotation processing and/or compilation is done.
</ERROR>
Process exitValue=2
  -processor <class1>[,<class2>,<class3>...]Names of the annotation processors to run; bypasses default discovery process
</ERROR>
Process exitValue=2
  -processorpath <path>      Specify where to find annotation processors
</ERROR>
Process exitValue=2
  -d <directory>             Specify where to place generated class files
</ERROR>
Process exitValue=2
  -s <directory>             Specify where to place generated source files
</ERROR>
Process exitValue=2
  -implicit:{none,class}     Specify whether or not to generate class files for implicitly referenced files 
</ERROR>
Process exitValue=2
  -encoding <encoding>       Specify character encoding used by source files
</ERROR>
Process exitValue=2
  -source <release>          Provide source compatibility with specified release
</ERROR>
Process exitValue=2
  -target <release>          Generate class files for specific VM version
</ERROR>
Process exitValue=2
  -version                   Version information
</ERROR>
Process exitValue=2
  -help                      Print a synopsis of standard options
</ERROR>
Process exitValue=2
  -Akey[=value]              Options to pass to annotation processors
</ERROR>
Process exitValue=2
  -X                         Print a synopsis of nonstandard options
</ERROR>
Process exitValue=2
  -J<flag>                   Pass <flag> directly to the runtime system
</ERROR>
Process exitValue=2
</ERROR>
Process exitValue=2

哎,不管怎么说还是出来了结果,作者作了一下总结,就是说,为了处理好外部命令大量输出的情况,你要确保你的程序处理好外部命令所需要的输入或者输出。

其实呀。还有其他,下篇再讲啦。


这会总算得到结果啦。不过在ubuntu里面跟在windows里面得到的结果有点不一样。

大家注意下。
分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

     用JAVA开发的一个小型的目录监视系统,系统会每5秒自动扫描一次需要监视的目录,可以用来监视目录中文件大小及文件增减数目的变化。 Java日期选择控件完整源代码 14个目标文件 内容索引:JAVA源码,系统相关,日历,...

    125集专攻JAVA基础 JAVA零基础入门学习视频教程 动力节点JAVA视频教程.txt

    北京动力节点-Java编程零基础教程-033-Java基本语法-注释-javadoc命令.avi 北京动力节点-Java编程零基础教程-034-Java基本语法-标识符.avi 北京动力节点-Java编程零基础教程-035-Java基本语法-关键字.avi 北京...

    Java开发技术大全(500个源代码).

    getLinePara.java 获取命令行参数示例 hasStaticMethod.java 静态成员方法示例 hasStatMember.java 静态成员变量示例 HelloNative.c 用C写的一个小程序 HelloNative.dll 用C生成的DLL文件 HelloNative.exp 用...

    JAVA上百实例源码以及开源项目

     用JAVA开发的一个小型的目录监视系统,系统会每5秒自动扫描一次需要监视的目录,可以用来监视目录中文件大小及文件增减数目的变化。 Java日期选择控件完整源代码 14个目标文件 内容索引:JAVA源码,系统相关,日历,...

    java中各种环境变量的配置

    我们先给系统配置一个JAVA_HOME的环境变量(目的是为了方便我们修改jdk的版本和第三方软件的调用).JAVA_HOME设为jdk的安装目录,如:D:\jdk1.6.0_21 2. 然后我们在为path配上jdk,设为%JAVA_HOME%\bin; classpath的...

    java内部学习笔记.docx

    2.14 Java系统API方法调用 14 2.15二进制基础 14 2.16 Java基础其他注意事项 14 面向对象 16 3.1类 16 3.2对象 16 3.3包 16 3.4方法及其调用 17 3.5引用 17 3.6访问控制(封装) 17 3.7构造器 17 3.8 super()、super...

    java图书馆swing源码-rcaller:用于调用R的Java库

    使用调用顺序命令功能,性能不会因为单个外部进程而丢失。 尽管 R 是单线程的,但 Java 中的多个 RCaller 实例可以创建和处理多个 R 进程。 基于 Servlet 的应用程序可以实例化许多 RCaller 对象,也可以通过使用...

    java 编程入门思考

    第10章 Java IO系统 10.1 输入和输出 10.1.1 InputStream的类型 10.1.2 OutputStream的类型 10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向...

    Java初学者入门教学

    第10章 Java IO系统 10.1 输入和输出 10.1.1 InputStream的类型 10.1.2 OutputStream的类型 10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向...

    java联想(中文)

    第10章 Java IO系统 10.1 输入和输出 10.1.1 InputStream的类型 10.1.2 OutputStream的类型 10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向...

    java初学者必看

    最近正在学习Java,也买了很多的有关Java方面的书籍,其中发现《跟我学Java》这本书,都的很不错啊,所以顺便拿电脑把这本书的目录敲了下来,与大家分享。尤其是那些和我一样初学Java的朋友们,看看哪一节对你有用,...

    疯狂JAVA讲义

    学生提问:老师,我想学习Java编程,到底是学习Eclipse好呢,还是学习JBuilder好呢? 21 1.9 本章小结 22 本章练习 22 第2章 理解面向对象 23 2.1 面向对象 24 2.1.1 结构化程序设计简介 24 2.1.2 程序的三种...

    JAVA_Thinking in Java

    第10章 Java IO系统 10.1 输入和输出 10.1.1 InputStream的类型 10.1.2 OutputStream的类型 10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向...

    Thinking in Java简体中文(全)

    第10章 Java IO系统 10.1 输入和输出 10.1.1 InputStream的类型 10.1.2 OutputStream的类型 10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向...

    基于Mysql+Java的进销存信息管理系统源码+sql数据库+项目说明.zip

    数据库的备份用到了mysql的mysqldump,调用了cmd命令执行mysqldump.exe 3.图片 【说明】 1、项目源码在上传前,都经过本地成功运行,功能测试无误。请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机...

    AIC的Java课程1-6章

     使用javac, java, appletviewer等命令编译和运行application和applet。 第2章 面向过程(变量和控制结构) 4课时  掌握变量的内存概念,8种基本类型,字面值和赋值。  正确使用各种Java...

    《C 语言实现 Linux Shell 命令解释器》项目.zip

    软件开发设计:应用软件开发、系统软件开发、移动应用开发、网站开发C++、Java、python、web、C#等语言的项目开发与学习资料 硬件与设备:单片机、EDA、proteus、RTOS、包括计算机硬件、服务器、网络设备、存储设备...

    Java基于Netty实现的高性能分布式IM即时通信系统源码+项目说明.tar

    Java基于Netty实现的高性能分布式IM即时通信系统源码+项目说明.tar 介绍 `RIM`是基于Netty实现的面相开发者的高性能分布式即时通信系统,保证消息的实时性、有序性、可靠性。 ## 技术栈 | 名称 | 作用 | | -------...

    Thinking in Java 中文第四版+习题答案

    第10章 Java IO系统 10.1 输入和输出 10.1.1 InputStream的类型 10.1.2 OutputStream的类型 10.2 增添属性和有用的接口 10.2.1 通过FilterInputStream从InputStream里读入数据 10.2.2 通过FilterOutputStream向...

Global site tag (gtag.js) - Google Analytics