#include <stdio.h>
int main() { /* 簡單地循環打印標準輸入上的兩個整數之和 */
int a, b, lineNumber = 0;
while (scanf("%d %d", &a, &b))
printf("Line# %d \t %d + %d == %d\n", ++lineNumber, a, b, a + b);
return 0;
}
以下的
Java 程序可以在啓動 adder.exe 後,跟 adder.exe 的標準輸入和輸出接軌,然後持續不斷地向
它發送數據和索取結果:
import java.io.*;
class C {
public static void main(String[] args) throws Exception {
final Process proc = Runtime.getRuntime().exec("adder.exe");
// 用另一個線程把參數送到 proc 的標準輸入上去。
new Thread() {
public void run() {
OutputStream stdin = proc.getOutputStream();
for (int i = 0; ; i++) {
try {
Thread.sleep(1); // 要休息片刻纔看得到 I/O 的緩存效果。
stdin.write((i + " " + i + "\n").getBytes());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}.start();
// 主線程負責讀取並打印 proc 的標準輸出。
BufferedReader stdout = new BufferedReader(new InputStreamReader
(proc.getInputStream()));
for (String line; null != (line = stdout.readLine()); )
System.out.println(line);
}
}
循環裏的 Thread.sleep(1) 純粹是爲了凸顯 I/O 的緩存效果。
我測試時看到大約 900 行的緩存量(用 32-bit XP 和
Java 1.6)。
有時候,需要在Java中調用現成的.exe文件或是cmd進行操作,下面結合自己的項目實例,做以小結。
現在我們的目標是:用Java調用cmd,執行C:/libsvm/windows/svm-train.exe,svm-train.exe參數爲:
[options] training_set_file [model_file]
具體是 -c 32 -g 0.0078125 trainset trainset.model
可以將doc窗口的輸出顯示到JAVA IDE的控制檯上。
我們需要用到java.lang.Runtime類
主要成員函數:
getRuntime() 返回與當前 Java 應用程序相關的運行時對象。
Runtime r=Runtime.getRuntime();
exec(String command, String[] envp, File dir) 在有指定環境和工作目錄的獨立進程中執行指定的字
符串命令。 。command爲.exe及其參數,envp null即可,dir=new File(FilePath)
java.lang.Process類
主要成員函數:
waitFor() 導致當前線程等待,如果必要,一直要等到由該 Process 對象表示的進程已經終止。
注:Process p = Runtime.getRuntime().exec(arg)
實現代碼如下:
- public static void main(String[] args) {
- try {
- Runtime r = Runtime.getRuntime();
- String[] cmd = new String[5];
- cmd[0] = "cmd "; //命令行
- cmd[1] = "/c "; //運行後關閉,
- cmd[2] = "start "; //啓動另一個窗口來運行指定的程序或命令(cmd 命令集裏的)
- cmd[3] = "C:\\windows"; //要運行的.exe程序的目錄
- cmd[4] = "svm-train -c 32 -g 0.0078125 -v 5 trainset ";//exe程序及其需要的參數
- String Naiveexe = "calc.exe";//windows自帶計算器
- String line;
- String space=" ";
- //Process p = Runtime.getRuntime().exec("cmd /c svm-train.exe -c 32 -g 0.0078125 -v 5 trainset",null,new File("C:\\libsvm\\windows")); 此時輸出到控制檯
- //Process p = Runtime.getRuntime().exec("cmd /c start svm-train.exe -c 32 -g 0.0078125 -v 5 trainset",null,new File("C:\\libsvm\\windows"));此時彈出dos窗口運行
- Process p = Runtime.getRuntime().exec((cmd[0]+cmd[1]+cmd[4]),null,new File(cmd[3]));
- //Process p = Runtime.getRuntime().exec("calc.exe"); //直接運行計算器
- BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
- while((line=br.readLine()) != null){
- System.out.println(line);
- //p.waitFor();
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
public static void main(String[] args) {
try {
Runtime r = Runtime.getRuntime();
String[] cmd = new String[5];
cmd[0] = "cmd "; //命令行
cmd[1] = "/c "; //運行後關閉,
cmd[2] = "start "; //啓動另一個窗口來運行指定的程序或命令(cmd 命令集裏的)
cmd[3] = "C:\\windows"; //要運行的.exe程序的目錄
cmd[4] = "svm-train -c 32 -g 0.0078125 -v 5 trainset ";//exe程序及其需要的參數
String Naiveexe = "calc.exe";//windows自帶計算器
String line;
String space=" ";
//Process p = Runtime.getRuntime().exec("cmd /c svm-train.exe -c 32 -g 0.0078125 -v 5 trainset",null,new File("C:\\libsvm\\windows")); 此時輸出到控制檯
//Process p = Runtime.getRuntime().exec("cmd /c start svm-train.exe -c 32 -g 0.0078125 -v 5 trainset",null,new File("C:\\libsvm\\windows"));此時彈出dos窗口運行
Process p = Runtime.getRuntime().exec((cmd[0]+cmd[1]+cmd[4]),null,new File(cmd[3]));
//Process p = Runtime.getRuntime().exec("calc.exe"); //直接運行計算器
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line=br.readLine()) != null){
System.out.println(line);
//p.waitFor();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
http://hi.baidu.com/469741414/blog/item/8b5a8289e22817dafd1f1086.html
使用Runtime.getRuntime().exec()方法可以在java程序裏運行外部程序.
該方法有6個可訪問版本:
1.exec(String command)
2.exec(String command, String envp[], File dir)
3.exec(String cmd, String envp[])
4.exec(String cmdarray[])
5.exec(String cmdarray[], String envp[])
6.exec(String cmdarray[], String envp[], File dir)
一般的應用程序可以直接使用第一版本,當有環境變量傳遞的時候使用後面的版本.
其中2和6版本可以傳遞一個目錄,標識當前目錄,因爲有些程序是使用相對目錄的,所以就要使用這個版本.
當要執行批處理的時候,不能直接傳遞批處理的文件名,而要使用:
cmd.exe /C start 批處理文件名
使用dos命令(比如dir)時也要使用掉調用.
如果想與調用的程序進行交互,那麼就要使用該方法的返回對象Process了,通過Process的getInputStream(),getOutputStream(),getErrorStream()方法可以得到輸入輸出流,然後通過InputStream可以得到程序對控制檯的輸出信息,通過OutputStream可以給程序輸入指令,這樣就達到了程序的交換功能.
例子如下:
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.OutputStreamWriter;
- import java.io.PrintWriter;
- public class ExecuteTask implements Runnable {
- private boolean isRunning = true;
- public ExecuteTask() {
- }
- public void run() {
- }
- public static void main(String[] args) {
- try {
- Process proc = Runtime.getRuntime().exec("cmd.exe");
- BufferedReader read = new BufferedReader(new InputStreamReader(
- proc.getInputStream()));
- new Thread(new Echo(read)).start();
- PrintWriter out = new PrintWriter(new OutputStreamWriter(
- proc.getOutputStream()));
- BufferedReader in = new BufferedReader(new InputStreamReader(
- System.in));
- String instr = in.readLine();
- while (!"exit".equals(instr)) {
- instr = in.readLine();
- out.println(instr);
- // file: // out.println("telnet 192.168.0.1");
- out.flush();
- }
- in.readLine();
- read.close();
- out.close();
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
- class Echo implements Runnable {
- private BufferedReader read;
- public Echo(BufferedReader read) {
- this.read = read;
- }
- public void run() {
- try {
- String l = read.readLine();
- while (l != null) {
- System.out.println(l);
- l = read.readLine();
- }
- System.out.println("---執行完畢:");
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class ExecuteTask implements Runnable {
private boolean isRunning = true;
public ExecuteTask() {
}
public void run() {
}
public static void main(String[] args) {
try {
Process proc = Runtime.getRuntime().exec("cmd.exe");
BufferedReader read = new BufferedReader(new InputStreamReader(
proc.getInputStream()));
new Thread(new Echo(read)).start();
PrintWriter out = new PrintWriter(new OutputStreamWriter(
proc.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(
System.in));
String instr = in.readLine();
while (!"exit".equals(instr)) {
instr = in.readLine();
out.println(instr);
// file: // out.println("telnet 192.168.0.1");
out.flush();
}
in.readLine();
read.close();
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
class Echo implements Runnable {
private BufferedReader read;
public Echo(BufferedReader read) {
this.read = read;
}
public void run() {
try {
String l = read.readLine();
while (l != null) {
System.out.println(l);
l = read.readLine();
}
System.out.println("---執行完畢:");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
http://blog.csdn.net/gavinming/article/details/5579799
今天遇到了個奇怪的問題,用VC寫了個小程序,編譯成exe文件,然後用Java去調,居然卡住不運行了。
如果雙擊這個exe程序,單獨讓它運行,是可以的,那麼爲什麼用Java調用就不好使了呢?
上網查了一下,原來是由於緩衝區的問題,也就是說Process的getErrorStream和getInputStream緩衝區沒有清空。我在VC裏要打印的東西太多了,以至於填滿了緩衝區,這是緩衝區需要釋放,我不但沒釋放還一個勁的運行程序,那麼Java就卡在那裏了。表面上好像是exe出了問題,其實是這個Process的緩衝區造成的。
解決方法:
InputStream is1 = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is1));
try {
while(br.readLine() != null) ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
InputStream is2 = process.getErrorStream();
if(null != is2) {
BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
StringBuilder buf = new StringBuilder(); // 保存輸出結果流
String line = null;
try {
while(br2.readLine() != null) ;
buf.append(line);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("輸出結果爲:" + buf.toString(());
}
將上述代碼加入程序就可以解決緩衝區的問題,建議單獨開啓線程去多。
我的代碼裏不需要getErrorStream()部分的代碼,這兩部分針對實際情況自由選擇。