如何在java中调用exe

假设我们已经把以下的 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)

实现代码如下:

  1. public static void main(String[] args) {  
  2.       
  3.     try {  
  4.         Runtime r = Runtime.getRuntime();  
  5.         String[] cmd = new String[5];  
  6.           
  7.         cmd[0] = "cmd "//命令行  
  8.         cmd[1] = "/c "//运行后关闭,  
  9.         cmd[2] = "start "//启动另一个窗口来运行指定的程序或命令(cmd 命令集里的)  
  10.         cmd[3] = "C:\\windows"//要运行的.exe程序的目录  
  11.           
  12.         cmd[4] = "svm-train -c 32 -g 0.0078125 -v 5 trainset ";//exe程序及其需要的参数  
  13.         String Naiveexe = "calc.exe";//windows自带计算器  
  14.         String line;  
  15.         String space=" ";  
  16.         //Process p = Runtime.getRuntime().exec("cmd /c svm-train.exe -c 32 -g 0.0078125 -v 5 trainset",null,new File("C:\\libsvm\\windows")); 此时输出到控制台  
  17.         //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窗口运行  
  18.         Process p = Runtime.getRuntime().exec((cmd[0]+cmd[1]+cmd[4]),null,new File(cmd[3]));  
  19.         //Process p = Runtime.getRuntime().exec("calc.exe"); //直接运行计算器  
  20.         BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));  
  21.         while((line=br.readLine()) != null){  
  22.             System.out.println(line);  
  23.             //p.waitFor();  
  24.         }  
  25.     } catch (IOException e) {  
  26.         // TODO Auto-generated catch block  
  27.         e.printStackTrace();  
  28.     }  
  29. }  
	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可以给程序输入指令,这样就达到了程序的交换功能.   
  例子如下:

  1. import java.io.BufferedReader;  
  2. import java.io.IOException;  
  3. import java.io.InputStreamReader;  
  4. import java.io.OutputStreamWriter;  
  5. import java.io.PrintWriter;  
  6.   
  7. public class ExecuteTask implements Runnable {  
  8.     private boolean isRunning = true;  
  9.   
  10.     public ExecuteTask() {  
  11.     }  
  12.   
  13.     public void run() {  
  14.     }  
  15.   
  16.     public static void main(String[] args) {  
  17.         try {  
  18.             Process proc = Runtime.getRuntime().exec("cmd.exe");  
  19.             BufferedReader read = new BufferedReader(new InputStreamReader(  
  20.                     proc.getInputStream()));  
  21.             new Thread(new Echo(read)).start();  
  22.             PrintWriter out = new PrintWriter(new OutputStreamWriter(  
  23.                     proc.getOutputStream()));  
  24.             BufferedReader in = new BufferedReader(new InputStreamReader(  
  25.                     System.in));  
  26.             String instr = in.readLine();  
  27.             while (!"exit".equals(instr)) {  
  28.                 instr = in.readLine();  
  29.                 out.println(instr);  
  30. //              file: // out.println("telnet   192.168.0.1");  
  31.                 out.flush();  
  32.             }  
  33.             in.readLine();  
  34.             read.close();  
  35.             out.close();  
  36.         } catch (IOException ex) {  
  37.             ex.printStackTrace();  
  38.         }  
  39.     }  
  40. }  
  41.   
  42. class Echo implements Runnable {  
  43.     private BufferedReader read;  
  44.   
  45.     public Echo(BufferedReader read) {  
  46.         this.read = read;  
  47.     }  
  48.   
  49.     public void run() {  
  50.         try {  
  51.             String l = read.readLine();  
  52.             while (l != null) {  
  53.                 System.out.println(l);  
  54.                 l = read.readLine();  
  55.             }  
  56.             System.out.println("---执行完毕:");  
  57.         } catch (IOException ex) {  
  58.             ex.printStackTrace();  
  59.         }  
  60.     }  
  61. }  
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()部分的代码,这两部分针对实际情况自由选择。

http://blog.sina.com.cn/s/blog_59c701350100q9l9.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章