之前曾經有使用過Java來執行外部執行檔(如:.exe),進而產生出所需要的結果檔案。
而在這邊主要是使用7za.exe執行檔來進行壓縮及解壓縮的動作,紀錄一下如果使用7za.exe
需要搭配什麼樣的指令才可以達到基本壓縮及解壓縮的動作,而也會討論到使用Process時
需要注意的一些事情。
基本上在使用Java來執行外部執行檔時,需要另外定義一process,相對主程式而言為
subprocess。process需要透過Runtime.getRuntime().exec(command)來產生實體,當下也已經
做執行的動作了。
而process本身有下列幾項的函式可以使用,如exitValue,可以得到執行結果,印出0表示正
常的終止;waitFor,表示主程式需等待subprocess執行完成,並回傳如exitValue的執行結果,
才會終止結束程式,但是如果subprocess執行的當下發生錯誤,會hang住主程式,導致無法
繼續正常運作。
在此,範例程式如下:
在這邊宣告zip_exe array,組成執行壓縮及解壓縮的指令
執行壓縮
參數1: 7za.exe的執行檔絕對路徑
參數2: a => 壓縮指令
參數3: -t7z 壓縮方式
參數4: 輸出壓縮檔的路徑
參數5: 檔案的來源路徑
ps. 假設參數5所帶入為相對路徑,檔案在壓縮的當下會將存放檔案的目錄一起壓縮進去,
填入絕對路徑的話,則壓縮檔內只有檔案本身!
解壓縮
參數1: 7za.exe的執行檔絕對路徑
參數2: x => 解壓縮指令
參數3: 壓縮檔案的來源路徑
參數4: -oC:\\目錄名稱
ps. 參數4 -o後的路徑為解壓縮後檔案存放的地方,若目錄不存在的話會自動建立!
當下的執行結果如下:
撇開註解掉的程式碼,當下如果執行的話,會出現錯誤!
主要訊息為 java.lang.IllegalThreadStateException: process has not exited
表示subprocess在還沒有執行完的當下,主程式就已經結束了,導致subprocess被不正常的
強制結束!!
此時將31行的程式改成 => exitVal = p.waitFor();
並且32 ~ 34行的InterruptedException catch註解也拿掉!
此時執行結果如下:
由上面曾經提到的waitFor功用,使得subprocess所執行的壓縮及解壓縮可以順利完成!
而我們還是決定改回exitValue,而程式又要順利執行,程式碼可以修改如下:
在此將讀取Process在執行7za.exe過程之中執行指令的InputStream資料,並且將此過程列印
出來,這個目的主要也代表了主程式當下也在等待subprocess的執行過程,如此一來可能不
會自行先結束!
而在這邊主要是使用7za.exe執行檔來進行壓縮及解壓縮的動作,紀錄一下如果使用7za.exe
需要搭配什麼樣的指令才可以達到基本壓縮及解壓縮的動作,而也會討論到使用Process時
需要注意的一些事情。
基本上在使用Java來執行外部執行檔時,需要另外定義一process,相對主程式而言為
subprocess。process需要透過Runtime.getRuntime().exec(command)來產生實體,當下也已經
做執行的動作了。
而process本身有下列幾項的函式可以使用,如exitValue,可以得到執行結果,印出0表示正
常的終止;waitFor,表示主程式需等待subprocess執行完成,並回傳如exitValue的執行結果,
才會終止結束程式,但是如果subprocess執行的當下發生錯誤,會hang住主程式,導致無法
繼續正常運作。
在此,範例程式如下:
public static void main(String[] args) {
// TODO Auto-generated method stub
String root = "C:\\Java program\\Java Zip";
String tmpFolderPath = root+"\\dirs\\*.txt";
String zipPath = "tools\\7za920";
SimpleDateFormat date_convert = new SimpleDateFormat("yyyyMMddHHmmss");
String report_dname = date_convert.format(new java.sql.Date(System.currentTimeMillis()));
String outFolderPath = "output\\"+report_dname+".7z";
String zip_exe[]={zipPath + "\\7za.exe","a","-t7z",outFolderPath,tmpFolderPath};
System.out.println("壓縮執行結果-Process exitValue: " + execCommand(zip_exe));
zip_exe=new String[]{zipPath + "\\7za.exe","x",outFolderPath, "-o"+root+"\\output\\"+report_dname};
System.out.println("解壓縮執行結果-Process exitValue: " + execCommand(zip_exe));
}
public static int execCommand(String zip_exe[]){
Process p = null;
InputStream in_b = null;
BufferedReader reader = null;
int exitVal = 0;
try{
p = Runtime.getRuntime().exec(zip_exe);
//in_b = p.getInputStream();
//reader = new BufferedReader(new InputStreamReader(in_b));
String str = null;
System.out.println("<output>");
// while ((str = reader.readLine()) != null){
// System.out.println(str);
// }
System.out.println("</output>");
exitVal = p.exitValue();
}/*catch(InterruptedException e){
e.printStackTrace();
}*/catch(IOException e){
e.printStackTrace();
}finally{
p.destroy();
// try {
// in_b.close();
// reader.close();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
return exitVal;
}
在這邊宣告zip_exe array,組成執行壓縮及解壓縮的指令
執行壓縮
參數1: 7za.exe的執行檔絕對路徑
參數2: a => 壓縮指令
參數3: -t7z 壓縮方式
參數4: 輸出壓縮檔的路徑
參數5: 檔案的來源路徑
ps. 假設參數5所帶入為相對路徑,檔案在壓縮的當下會將存放檔案的目錄一起壓縮進去,
填入絕對路徑的話,則壓縮檔內只有檔案本身!
解壓縮
參數1: 7za.exe的執行檔絕對路徑
參數2: x => 解壓縮指令
參數3: 壓縮檔案的來源路徑
參數4: -oC:\\目錄名稱
ps. 參數4 -o後的路徑為解壓縮後檔案存放的地方,若目錄不存在的話會自動建立!
當下的執行結果如下:
撇開註解掉的程式碼,當下如果執行的話,會出現錯誤!
主要訊息為 java.lang.IllegalThreadStateException: process has not exited
表示subprocess在還沒有執行完的當下,主程式就已經結束了,導致subprocess被不正常的
強制結束!!
此時將31行的程式改成 => exitVal = p.waitFor();
並且32 ~ 34行的InterruptedException catch註解也拿掉!
此時執行結果如下:
由上面曾經提到的waitFor功用,使得subprocess所執行的壓縮及解壓縮可以順利完成!
而我們還是決定改回exitValue,而程式又要順利執行,程式碼可以修改如下:
try{
p = Runtime.getRuntime().exec(zip_exe);
in_b = p.getInputStream();
reader = new BufferedReader(new InputStreamReader(in_b));
String str = null;
System.out.println("<output>");
while ((str = reader.readLine()) != null){
System.out.println(str);
}
System.out.println("</output>");
exitVal = p.exitValue();
}/*catch(InterruptedException e){
e.printStackTrace();
}*/catch(IOException e){
e.printStackTrace();
}finally{
p.destroy();
try {
in_b.close();
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
在此將讀取Process在執行7za.exe過程之中執行指令的InputStream資料,並且將此過程列印
出來,這個目的主要也代表了主程式當下也在等待subprocess的執行過程,如此一來可能不
會自行先結束!
留言
張貼留言