Process ps = ().exec("");
();
()返回当前应用程序的Runtime对象,该对象的exec()方法指示Java虚拟机创建一个子进程执行指定的可执行程序,
并返回与该子进程对应的Process对象实例。通过Process可以控制该子进程的执行或获取该子进程的信息。
它的所有标准io(即stdin,stdout,stderr)操作都将通过三个流(getOutputStream(),getInputStream(),getErrorStream())重定向到父进程。
父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读
写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
()的目的是等待子进程完成再往下执行。
也就是说:如果程序不断在向标准输出流和标准错误流写数据,而JVM不读取的话,当缓冲区满之后将无法继续写入数据,最终造成阻塞在waifor()这里。
执行一个有标准输出的DOS可执行程序在windows平台上,运行被调用程序的DOS窗口执行完毕后往往并不会自动关闭,从而导致Java应用
程序阻塞在waitfor()。导致该现象的一个可能的原因是,该可执行程序的标准输出比较多,而运行窗口的标准输出缓冲区不够大。
解决的办法是, 利用Java提供的Process类提供的方法让Java虚拟机截获被调用程序的DOS运行窗口的标准输出,在waitfor()命令之前读出
窗口的标准输出缓冲区中的内容。
InputStream getErrorStream():获得子进程的错误流
InputStream getInputStream():获得子进程的输入流
可以考虑使用两个线程来同时清空process获取的两个输入流。
创建线程方法之一:实现Runnable接口
步骤:
1.定义类实现Runnable接口
2.重写run()方法,这个方法里面实现的是实际要做的操作。
3.定义一个方法,在里面实现该类的线程,同时调用线程的start()方法
例:public void start(){
Thread thread = new Thread(this);
(true);设置成守护线程
();
}
public class ProcessUitl implements Runnable{
public String getErrStr() {
return errStr;
}
public void setErrStr(String errStr) {
= errStr;
}
//设置读取的字符编码
private String character = "utf-8";
private InputStream inputStream;
private String errStr = null;
public ProcessUitl(InputStream inputStream) {
= inputStream;
}
@Override
public void run() {
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(inputStream, character));//以utf-8的编码格式去读取文件
String line = null;
StringBuilder sb = new StringBuilder();
while((line = ()) != null){
(line);
}
errStr = ();
} catch (UnsupportedEncodingException e) {
();
} catch (IOException e) {
();
}finally{
if(br != null){
try {
();
} catch (IOException e) {
();
}
}
if(inputStream != null){
try {
();
} catch (IOException e) {
();
}
}
}
}
public void start(){
Thread thread = new Thread(this);
(true);
();
}
public static void main(String[] args) {
String command = "ping ";
Process ps = null;
try {
ps = ().exec(command);
ProcessUitl pu = new ProcessUitl(());
().close();
();
String errorStr = ();
if(errorStr != null){
("Error!!!!!");
}
} catch (IOException e) {
();
} catch (InterruptedException e) {
();
}finally{
if(ps != null){
();
}
}
}
}
转载:以下部分
步骤:
1.定义实现Runnable接口
2.覆盖Runnable接口中的run方法,将线程要运行的代码存放在run方法中。
3.通过Thread类建立线程对象。
4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
为什么要讲Runnable接口的子类对象传递给Thread的构造方法。因为自定义的方法的所属的对象是Runnable接口的子类对象。
5.调用Thread类的start方法开启线程并调用Runnable接口子类run方法。