技术开发 频道

JAVA平台进程间协作应用集锦

  【IT168 技术文档】摘要:本文介绍了在JAVA平台通过多个进程间的“无缝协作”来实现借助已有进程来帮助开发人员来完成特定任务的一些经典实践。巧妙地使用外部进程,不仅可以极大减少系统的开发成本,也可以提高系统的稳定性和执行效率。

  一、引言

  无论对于哪个平台,进程间的协作都是亮点之一。通过进程间的协作我们可以总合成熟,公共的执行文件来实现自己一些特定的功能(例如:通过数据库工具来实现数据库操作,通过编译工具来实现动态代码的编译等)。所以,无论是在Windows平台还是Unix平台,都提供了进程间协作的机制。例如:Unix和Windows平台下的批处理技术,管道技术等,都是通过利用一些外部进程来实现本进程无法实现的内容。

  作为JAVA平台,对进程间协作的支持更加简单。JAVA定义了专门的进程I/O流,通过这些进程I/O流,我们就实现进程间的“无缝协作”。

  所谓无缝,是指进程之间并不是简单的调用关系,而是表现为多个进程的合为一体。就像Unix和Windows平台中创建子进程,父进程通过向子进程传递信息来驱动子进程完成任务,子进程执行完毕之后,还会将执行结果反馈给父进程。整个过程似乎只执行一个进程而已。相比之下,JAVA平台实现进程间的无缝连接要比上述的Unix或Windows平台要简单得多。

  二、进程间协作的实现过程

  (1)通过Runtime类的静态方法getRuntime来获取Runtime对象

  (2)通过Runtime类的exec方法来执行可执行文件命令行(可带参数)并获取子进程对象Process pJavac = Runtime.getRuntime()。exec(command);

  (3)将子进程对象的错误流或者输出流作为输入流,并对其进行读取

  InputStreamReader isr_error = new InputStreamReader(pJavac.getErrorStream() );   InputStreamReader isr_normal = new InputStreamReader(pJavac.getInputStream() );   //Get the error output from javac   while( (ch = isr_error.read() ) != -1)   {   strbuf_error.append((char)ch);   }

  (4)等待子进程执行完毕(通过Process类的waitFor方法),即可对子进程输出流进行分析

  //Wait for javac process finish   pJavac.waitFor();

  注意:步骤(4)是必须的,否则读取到的输出可能会不完整。这一点在很多例子中没有讲到。

  读者不难看出,与函数,线程调用不同的是,进程间的创建是重量级的,一般都需要开辟单独的进程空间。对于开发人员而言,很多工具都难使用其内部的函数资源的,即使可以通过动态链接库进行函数载入,但是该过程往往也是相当麻烦。

  三、进程间协作的应用技巧

  以下是笔者根据诸多应用收集的进程间协作的应用技巧。

  1、编译java源代码

  通过调用JDK中JAVAC可执行文件对JAVA源文件进行编译,并输出编译结果(如果错误)。即使开发人员不清楚JAVA编译器的工作内容,也可以通过自己的JAVA程序调用javac进程来实现对JAVA代码的编译。实际上,在tomcat系统中,对JSP的源文件的编译,就是使用了标准的JAVA编译工具。

  命令行:java

  小评:该应用主要用于动态语句生成的场合。例如:(1)在JSP的应用中,先将JSP文件转换成JAVA源代码,在编译生成文件。

  (2)IDE环境中,用户生成代码,并对代码进行编译。

  (3)在客户端通过表单(Form)收集用户的代码,通过服务器端对代码进行存储编译。

  2、执行java类文件

  同前面的JAVA代码编译,调用JDK中的java可执行文件就可以实现对class文件的执行。并输出编译结果或者作为界面输出。例如:众多JAVA IDE工具,就是执行java来执行class文件。不同的是:java命令生成的子进程,不仅需要读取错误流,而且还要读取输出流。不仅需要读取执行的错误信息,还要读取执行的正确信息。如果是UI程序正常执行,那么输出流和错误流都将没有内容输出。

  命令行:java –cp<类文件所在目录> <类名>

  小评:该应用主要用于动态执行类文件的场合。例如:(1)IDE环境中,用户生成代码,并对代码进行编译。

  (2)在客户端通过表单(Form)收集用户的代码,通过服务器端对代码进行存储编译和执行。

  (3)执行类的管理,实现类文件的“按名执行”。

  3、执行MS SQL Server SQL或数据库脚本

  这里是通过调用MS SQL Server的osql工具来执行SQL语句或者脚本文件,避开了使用JDBC或ODBC来连接MS SQL Server数据库进行操作。而且osql与MS SQL Server采用的都是相同系统的接口,执行效率也较高。

  命令行:(1)执行SQL语句,输出到指定文件osql –S<主机名> -d<数据库名> -U<用户名> -P<密码> -Q -o<输出文件路径>(2)执行SQL脚本文件,输出到指定文件osql –S<主机名> -d<数据库名> -U<用户名> -P<密码> -i<脚本文件路径> -o<输出文件路径>

  等待执行完毕之后,可以通过文件流对输出的文件进行错误分析,给出相应的提示。

  该应用只适合于Windows,MS SQL Server数据库,执行次数不宜过多(毕竟进程的启动开销是比较大的),但是单次执行的任务量可以多一些。例如:通过语句或者脚本向数据库表批量插入数据等。

  4、将文件数据插入到MySQL数据库

  这里是通过mysqlimport工具,将文件数据批量插入到MySQL数据库。也不需要通过JDBC来进行连接。而且执行效率也相当高。

  执行命令为:mysqlimport <数据库名> <数据文件路径>其中数据库文件名为数据库中表名。

  例如:phome库中存在一个user_info的数据表。

  mysqlimport phome /usr/paul/mysql/data/user_info.txt就可以实现将user_info中的内容导入到phome库的user_info表中。

  该应用可以用于所有支持MySQL的平台。而且mysqlimport导入数据的效率远比JDBC函数要高得多。

  四、结束语

  通过上述的说明,大家都可以得出一个结论:在JAVA平台实现进程间协作相当简单;但是通过这些进程调用我们可以很高效,方便地完成各种平台相关的任务。包括:文件编译,数据库处理等。

  虽然进程调用属于重量级引用,但是我们只要把握进程调用的原则:调用次数不宜过多,但是单次任务量可以饱和一些。这样,我们就可以扬长避短,真正做到了进程调配的“集百家之长而为我所用”。

0
相关文章