快速业务通道

教你在Java中执行其它程序 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-14
出异常。

6、阻塞的问题

由Process代表的进程在某些平台上有时候并不能很好的工作,特别是在对代表进程的标准输入流、输 出流和错误输出进行操作时,如果使用不慎,有可能导致进程阻塞,甚至死锁。

如果将以上事例中的从标准输出重读取信息的语句修改为从错误输出流中读取:

stdout = new BufferedReader(new InputStreamReader(p .getErrorStream ()));

那么程序将发生阻塞,不能执行完成,而是hang在那里。

当进程启动后,就会打开标准输出流和错误输出流准备输出,当进程结束时,就会关闭他们。在以上 例子中,错误输出流没有数据要输出,标准输出流中有数据输出。由于标准输出流中的数据没有被读取, 进程就不会结束,错误输出流也就不会被关闭,因此在调用readLine()方法时,整个程序就会被阻塞。为 了解决这个问题,可以根据输出的实际先后,先读取标准输出流,然后读取错误输出流。

但是,很多时候不能很明确的知道输出的先后,特别是要操作标准输入的时候,情况就会更为复杂。 这时候可以采用线程来对标准输出、错误输出和标准输入进行分别处理,根据他们之间在业务逻辑上的关 系决定读取那个流或者写入数据。

针对标准输出流和错误输出流所造成的问题,可以使用ProcessBuilder的redirectErrorStream()方法 将他们合二为一,这时候只要读取标准输出的数据就可以了。

当在程序中使用Process的waitFor()方法时,特别是在读取之前调用waitFor()方法时,也有可能造成 阻塞。可以用线程的方法来解决这个问题,也可以在读取数据后,调用waitFor()方法等待程序结束。

总之,解决阻塞的方法应该有两种:

教你在Java中执行其它程序(5)

时间:2011-10-02 Java学习室 终南

(1)使用ProcessBuilder类,利用redirectErrorStream方法将标准输出流和错误输出流合二为一, 在用start()方法启动进程后,先从标准输出中读取数据,然后调用waitFor()方法等待进程结束。

如:

import java.io.BufferedReader; import java.io.File; import  java.io.InputStreamReader; import java.util.ArrayList; import  java.util.List; public class Test3 { public static void main(String[] args)  { try { List list = new ArrayList(); ProcessBuilder pb = null; Process  p = null; String line = null; BufferedReader stdout = null; //list the files and directorys under C:\ list.add("CMD.EXE"); list.add("/C"); list.add("dir"); pb = new ProcessBuilder (list); pb.directory(new File("C:\\")); //merge the error output with the standard output pb.redirectErrorStream (true); p = pb.start(); //read the standard output stdout = new  BufferedReader(new InputStreamReader(p .getInputStream())); while ((line =  stdout.readLine()) != null) { System.out.println(line); } int ret =  p.waitFor(); System.out.println("the return code is " + ret); stdout.close (); } catch (Exception e) { e.printStackTrace();

教你在Java中执行其它程序(6)

时间:2011-10-02 Java学习室 终南

(2)使用线程

import java.util.*; import java.io.*; class StreamWatch extends Thread  { InputStream is; String type; List output = new ArrayList (); boolean debug = false; StreamWatch(InputStream is, String type)  { this(is, type, false); } StreamWatch(InputStream is, String type,  boolean debug) { th

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号