假设我们已经把以下的 C 程序编绎成 adder.exe:
#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();
}
}
使用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可以给程序输入指令,这样就达到了程序的交换功能.
例子如下:
package com.broadcontact.netadmin.schedule;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.io.StringReader;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.File;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
/**
* <p>Title: netadmin</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2002</p>
* <p>Company: nm group</p>
* @author Maico(Panghf)
* @version 1.0
*/
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();
}
}
}