Java Runtime
1.exe-t「...」というexeファイルがあり、結果をコンソールに出力します.プログラムで呼び出し、出力結果を取得したいです.
主にcmdProcess.waitForおよびcmdProcess.getInputStream()の処理に注意する
waitFor関数の役割は,cmdProcessが終了するまで主スレッドをブロックすることである. getInputStream()は、入力ストリームとしてcmdProcessの出力ストリームを得る.
最初はずっと悩んでいましたが、cmdProcess.waitFor()は位置1に置くべきか位置2に置くべきか2.最初は位置2に置くと、ストリームの内容を読むときにcmdProcessがまだ実行されていないのではないかと思っていましたが、結果が出力されず、ストリームの中に何も読めませんでした.
後に実験を行い、cmdBrがcmdProcess.getInputStream()をキャプチャしたため、cmdBrを呼び出すと、cmdProcessがまだ出力されていないか、出力がまだ終了していない場合、ここでブロックされることが分かった.cmdProcessが出力され、終了子が出力されるまで.
次は実験方法です.Cプログラムを書いてhello worldを出力します.
hello world
main process: hello world
line 3にブロックがなければmain process:hello worldを先に出力するに違いない.test.exeがループしているので(オペレーティングシステムの授業では、プロセス実行の前後順を仮定することはできませんが、ここで十分です).
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() + "
");
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();
}
}
}
}
主にcmdProcess.waitForおよびcmdProcess.getInputStream()の処理に注意する
waitFor関数の役割は,cmdProcessが終了するまで主スレッドをブロックすることである. getInputStream()は、入力ストリームとしてcmdProcessの出力ストリームを得る.
最初はずっと悩んでいましたが、cmdProcess.waitFor()は位置1に置くべきか位置2に置くべきか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
line 3にブロックがなければmain process:hello worldを先に出力するに違いない.test.exeがループしているので(オペレーティングシステムの授業では、プロセス実行の前後順を仮定することはできませんが、ここで十分です).