网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.将一图片同比例缩小绘制.
.加法赋值运算符 (+=).
.取余运算符 (%).
.Java开发应用软件JCreator的使用.
.OReilly新书推荐:《游戏开发物理.
.泛型爪哇(Generic Java).
.用Java实现自动在数据库表中生成.
.用Axis开发基于Java的Web服务.
.RMI原理及实现.
.javac-----Java编程语言编译器.
.工欲善其事必先利其器 Java开发工.
.Java多国语言问题解决方案.
.JBuilder X 初体验.
.利用Java Swing 实现游戏开发.
.JSF是初学者进入Java Web世界的跳.
.tomcat配置技巧(转载).
.非常不错的SCJP真题回忆.
.利用JAVACC将HQL->SQL.
.Java 进阶:分享 Struts 多模块的.
.用Eclipse进行可视化Java界面设计.

详细讲解怎样在Java中运行其它应用程序

发表日期:2008-1-5



  import Java.io.*;
  
  public class CommandWrapper
  {
  Process process;
  Thread in;
  Thread out;
  public CommandWrapper(Process process)
  {
  this.process = process;
  final InputStream inputStream =
  process.getInputStream();
  //final BufferedReader
  r=new BufferedReader
  (new InputStreamReader(inputStream));
  final byte[] buffer = new byte[1024];
  out = new Thread()
  {
  //String line;
  int lineNumber=0;
  public void run()
  {
  try {
  while (true)
  {
  int count = inputStream.read(buffer);
  System.out.println
  (lineNumber+":"+new String
  (buffer, 0, count-1));
  //line=r.readLine();
  //System.out.println
  (lineNumber+":"+line);
  lineNumber++;
  }
  }
  catch (Exception e)
  {
  
  }
  }
  };
  final BufferedReader reader =
  new BufferedReader
  (new InputStreamReader(System.in));
  final OutputStream
  outputStream = process.getOutputStream();
  in = new Thread()
  {
  String line;
  public void run()
  {
  try
  {
  while (true)
  {
  outputStream.write(
  (reader.readLine()+"\n").getBytes());
  outputStream.flush();
  }
  }
  catch (Exception e)
  {
  
  }
  }
  };
  }
  
  public void startIn()
  {
  in.start();
  }
  
  public void startOut()
  {
  out.start();
  }
  
  public void interruptIn()
  {
  in.interrupt();
  }
  
  public void interruptOut()
  {
  out.interrupt();
  }
  
  public static void main
  (String[] args)
  {
  try
  {
  CommandWrapper command
  = new CommandWrapper
  (Runtime.getRuntime().exec("native2ascii"));
  command.startIn();
  command.startOut();
  }
  catch (Exception e)
  {
  e.printStackTrace();
  }
  }
  
  }
  
  我以native2ascii为范例程序和网友给我的那个程序做了对比,发现如下几个在处理这个问题时需要注重的地方:
  
  1、由于不知道目标程序的输入输出顺序,因此只能建立两个单独的线程分别处理输入和输出,这样输入和输出就不会阻塞了。但是有些目标程序要求有特定的输入输出顺序,而经过这个类封装的结果是在任何状态下都可以输入,程序的任何输出也会被马上反映出来。这是构造通用类的第一个问题。
  
  2、不能直接使用I/O重定向,在最开始的时候我是考虑直接使用I/O重定向的,但是实际的情况是Process的I/O的定义刚好和我的预想相反,我们从Process取得的InputStream实际上是它的输出,而取得的OutputStream是它的输入,这样就无法进行I/O重定向了,必须我们进行编码来读取程序的输出和写入控制台的输入。(这里的I/O重定向是指想将它的I/O直接重定向到系统的I/O)
  
  3、写入控制台的输入:
  
  outputStream.write(
  (reader.readLine()+"\n").getBytes());
  outputStream.flush();
  
  这里有两个问题值得注重:第一个是我们在控制台输入一行数据以后按下回车,那么语句reader.readLine()可以正确的得到你的输入,为什么要加那个换行符呢?这是在测试的时候发现的问题,在以native2ascii作为例子的时候发现不加这个的话它不能得到控制台的输入,但是我在替那位网友解决的问题的时候他的程序则没有这个问题。
  
  因此猜想可能是因为有的程序要求读取的一整行的数据(例如native2ascii),而大部分的命令行程序在编码的时候读取的是整数这样的值或者其他类型的值,他们是以空格或者其他的字符分隔的,因此就不需要那个额外的换行符(例如那位网友的程序读取的是一元二次方程的三个系数)。
  
  另外一个问题就是flush方法的使用,在最开始的时候没有想到要这样刷新进去,无论是否加换行符外部程序都无法读取写入的输入,后来才想到要调用一下这个方法。这个也是在我们输出的时候应该注重的一个问题,有些需要马上反应出来的输出一般都在写入以后要调用它,否则输出/输入不能马上反应出来。
  
  4、对于程序的输出,最开始我是构造的一个BufferedReader想以行为单位输出,对于那位网友的程序,结果证实不是很好用,但是以native2ascii作为例子运行又没有问题。这个估计和外部程序的代码也有关系,假如外部程序没有输出换行符可能使用BufferedReader就会有问题。但是通过直接读取输出就没有问题了。另外需要注重的就是:
  
  System.out.println
  (lineNumber+":"+new String
  (buffer, 0, count-1));
  
  中严格来说应该是:
  
  System.out.println
  (lineNumber+":"+new String
  (buffer, 0, count));
  
  之所以减一是因为读取输入的时候人为的多加了一个换行符,假如这个地方不减一就会多输出一个空行。
  
  基于以上的种种原因,要构造一个执行外部程序的包装器类不太好办,非凡是文章中提到的几个问题。有时间和爱好的朋友可以做一下测试,看看以上的问题和猜测是否正确。
  
  另外附上一段源代码,是一个fortran的程序:
  
  implicit none
  real a,b,c
  real d
  real root1,root2
  print*,'请输入一元二次方程
  的系数a,b,c:'
  read(*,*) a,b,c
  d=b**2-4.0*a*c
  if(d>=0.0) then
  root1=(-b+sqrt(d))/(2.0*a)
  root2=(-b-sqrt(d))/(2.0*a)
  print*,'root1=',root1
  print*,'root2=',root2
  else
  print*,'一元二次方程没有实根!'
  end if
  pause
  end
上一篇:Java Web 服务学习报告—Web简介 人气:613
下一篇:Java程序的脏数据问题处理 人气:551
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐