1. 程式人生 > >Java呼叫cmd命令遇到的坑總結

Java呼叫cmd命令遇到的坑總結

舉個栗子:

public class test {
	
	public static void main(String[] args){
		//執行計算
		execute("c:\\folder","book.txt");

	}

	public static void execute(String path, String inpFileName){

		Runtime rm = Runtime.getRuntime();
		try {
			//將c盤folder下的book.txt複製一份命名為book222.txt,放在c盤folder下
			String step = "cmd /c copy c:\\folder\\book.txt c:\\folder\\book222.txt";
			
			//執行命令
			Process process = rm.exec(step);
			
			System.out.println("執行完畢");
			
			//關閉流釋放資源
			if(process != null){
				process.getOutputStream().close();
			}
			
			
			InputStream in = process.getInputStream();
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String tmp = null;
			while ((tmp = br.readLine()) != null) {
	
			}
			

			//執行完畢之後將cmd命令複製的book222.txt 用Java程式碼複製到book333.txt
			File result = new File("c:\\folder" + File.separator + "book333.txt");

			FileInputStream fis = new FileInputStream(new File("c:\\folder\\book222.txt"));
			FileOutputStream fos = new FileOutputStream(result);
			int len;
			byte[] b = new byte[1024];
			while((len = fis.read(b)) != -1){
				fos.write(b, 0, len);
			}
					

		}catch(Exception e){
			e.printStackTrace();
			System.out.println("執行命令時出錯");
		}
	}
	

	public static void print(Process process) throws Exception{
		//以下為讀取cmd視窗返回的內容
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
		StringBuffer sb = new StringBuffer();
	        String line = null;
	        while ((line = bufferedReader.readLine()) != null) {  
	            sb.append(line).append("\n");
	        }

        	System.out.println(sb.toString());
	
	}

}


坑總結:

cmd命令中 "/" 符號和 "\"符號

\是cmd命令中的路徑分隔符 比如C:\Users\SYSTEM32
/是命令引數字尾,比如  format /q

所以在java中拼cmd的命令時的路徑 要用轉義符"\" 寫成"\\"

cmd中執行的好好的命令, java呼叫時候怎麼報錯呢?

我們在cmd中直接輸入  del  c:\test\book.txt鍵入回車,會直接將 對應路徑下的book.txt刪除 但是在java中執行 rm.exec("del c:\\test\\book.txt")就會報java.io.IOException: Cannot run program "del" 這是why? 這裡總結一下, Java中呼叫cmd命令, 要開局一個
cmd /c …… 如:String command = "cmd /c del c:\\test\\book.txt " 總結一下 cmd /c 和 cmd /k 的區別:

cmd /c dir:是執行完dir命令後關閉命令視窗;

cmd /k dir:是執行完dir命令後不關閉命令視窗。

cmd /c start dir:會開啟一個新視窗後執行dir指令,原視窗會關閉;

cmd /k start dir:會開啟一個新視窗後執行dir指令,原視窗不會關閉。


比如我的命令是執行某個bat程式, 之後會生成一個檔案, 然後我要通過java程式碼把這個檔案複製到另一個地方,可是bat程式還沒有執行完畢就執行了Java程式碼,導致找不到檔案, 那麼我們該如何判斷cmd命令是否執行完畢並在執行完畢後進行操作
呢?

首先看到網上有說用process.waitFor()方法的,這個方法具體是幹嘛的反正我沒試出來效果, 只是呼叫了以後程式就會停到那,不往下走了,並沒有解決我的問題, 然後發現可以通過流讀取列印cmd的輸出,於是用以下辦法
	Process process = rm.exec(step);
						
	//關閉流釋放資源
	if(process != null){
		process.getOutputStream().close();
	}
					
	InputStream in = process.getInputStream();
	BufferedReader br = new BufferedReader(new InputStreamReader(in));
	String tmp = null;
	while ((tmp = br.readLine()) != null) {
		// do nothing...啥也不幹
	}

	//程式碼執行到while迴圈以外,就說明cmd命令執行完畢了,檔案也生成了,就可以進行我們的複製或其它操作了……
需要注意的是, 呼叫完exec命令後, 要首先關閉process的outputStream, 然後再讀取, 不然程式依然會卡到那裡不動

exec()完命令後彈出的黑框框停那不動了,也不向下執行是為什麼?

Process process = rm.exec(command);
						
//關閉流釋放資源
if(process != null){
	process.getOutputStream().close();
}
呼叫完exec方法後, 要通過以上方式關流, 才能正確繼續向下執行,不知道為啥,這是我試出來的,參考上一條,不知是所有情況下都會發生,還是關流和列印一起使用時候的矛盾

如何一次呼叫執行多條cmd指令?

在命令字串中使用"&&" 拼接多條命令

複製檔案時候還遇見了一個java.io.FileNotFoundException(拒絕訪問。) 的錯誤

這是一個非常初級的知識,因為有一段時間沒有操作I/O流了, 而且感覺這裡內容太簡單,就隨便那麼一寫,沒想到有些問題沒注意到, 開始還以為是複製到c盤時候的許可權問題, 浪費了一些不必要的時間。