有一个exe文件,用法是 1.exe -t "...." , 它会把结果输出到控制台。 我想在程序里面调用它,并拿到输出结果。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
public class Test {
public static void main(String[] args) {
Process cmdProcess = null;
BufferedReader movieBr = null;
BufferedReader cmdBr = null;
BufferedWriter wholeBw = null;
BufferedWriter primaryBw = null;
String[] cmd = { "title.exe", "-t", "" };
String movieLine, cmdLine;
try {
movieBr = new BufferedReader(
new FileReader(
"movies.dat"));
wholeBw = new BufferedWriter(new FileWriter(
"whole.info"));
primaryBw = new BufferedWriter(new FileWriter(
"primary.info"));
while ((movieLine = movieBr.readLine()) != null) {
String[] tmp = movieLine.split("::");
System.out.println(tmp[0]);
cmd[2] = tmp[1];
cmdProcess = Runtime.getRuntime().exec(cmd);
cmdBr = new BufferedReader(new InputStreamReader(
cmdProcess.getInputStream())); //1
boolean flag = false;
while ((cmdLine = cmdBr.readLine()) != null) {
wholeBw.write(cmdLine);
if (flag) {
primaryBw.write(tmp[0] + "::" + cmdLine.trim() + "\n");
flag = false;
}
if (cmdLine.equals("Director:")) {
flag = true;
}
} //2
cmdProcess.waitFor();
}
wholeBw.flush();
primaryBw.flush();
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if(movieBr != null){
movieBr.close();
}
if(wholeBw != null){
wholeBw.close();
}
if(primaryBw != null){
primaryBw.close();
}
} catch (Exception e){
System.out.println("close stream error!");
e.printStackTrace();
}
}
}
}
waitFor函数的作用是让主线程阻塞,直到cmdProcess结束。 getInputStream()得到cmdProcess的输出流,作为输入流。
开始一直在纠结,cmdProcess.waitFor()是应该放到位置1还是位置2. 开始我以为,如果放到位置2, 会不会在读流的内容时,cmdProcess还没执行完,这样就没有输出结果,流里面就没读到东西。
后面做了一个实验,发现,由于cmdBr捕获了cmdProcess.getInputStream(), 那么当调用cmdBr时,如果cmdProcess还没有输出,或者输出还没有结束,这里就会阻塞。直到cmdProcess输出并且输出结束符。
下面是实验方法。 写了一个C程序,输出hello world。
#include<iostream>
using namespace std;
int main()
{
int n=INT_MAX;
while(n--);
cout<<"hello world"<<endl;
}
然后是测试程序,调用这个exe文件
public class TTT {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Process cmdProcess = null;
String[] cmd = { "test.exe" };
try {
cmdProcess = Runtime.getRuntime().exec(cmd);
BufferedReader cmdBr = new BufferedReader(new InputStreamReader(
cmdProcess.getInputStream()));
System.out.println(cmdBr.readLine()); // line 3
System.out.println("main process: hello world");
} catch (Exception e) {
e.printStackTrace();
}
}
}
过了若干秒之后,才开始输出结果
hello world
main process: hello world
如果在line3没有阻塞的话,那么肯定是先输出main process: hello world的。因为test.exe循环了那么就(虽然我们操作系统课上,老师说不能假定进程执行的先后顺序,但是用在这里已经足够了)。