最近在開發的時候,遇到java呼叫C#exe程式的時候,通過Process執行,一般C#程式都有紀錄檔輸出,但是通過Java怎麼獲取呢?這其中又會遇到一些什麼問題呢?
想通過C#小程式上傳檔案到伺服器,通過Process執行exe檔案,但是上傳成功與否,要通過小程式的紀錄檔來分析,但怎麼獲取紀錄檔呢?百度了一下,通過字元型輸入流就可以,雖然功能實現了,但不知道為什麼?
public static boolean uploadFileByFtp(String path) {
try {
Process pro = Runtime.getRuntime().exec("cmd /c " + "D:\\tool\\uploadFileByFtp.exe" + " " + path);
BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));
String line = null;
String ret = "";
while ((line = br.readLine()) != null) {
ret = ret + line + "\n";
}
if (ret.toString().contains("success")) {
return true;
} else {
return false;
}
} catch (Exception e) {
log.error("uploadFileByFtp exception:{}", e);
}
return false;
}
雖然功能實現了,但感覺缺少點什麼?
waitFor()函數表示,等待子程序執行結束,或者已手動終止子程序,此方法立即返回,否則出於阻塞狀態。
當RunTime物件呼叫exec方法後,jvm會建立一個子程序,該子程序與jvm建立三個管道連線:標準輸入流、標準輸出流、標準錯誤流。假設該子程序不斷向標準輸入流、標準輸出流寫資料,而jvm不讀取的話,會導致緩衝區塞滿而無法繼續寫資料,最終堵塞在waitFor這裡。
問題的關鍵就是,將緩衝區中的資訊讀出來,便可以避免執行緒阻塞問題。
public static boolean uploadFileByFtp2() {
try {
String path = "D:tool\\LogDataCollector\\log.txt";
File filePath = new File(path);
Process pro = Runtime.getRuntime().exec("cmd /c " + "D:\\tool\\uploadFileByFtp.exe" + " " + path);
pro.waitFor();
List<String> logs = FileUtils.readLines(new File(path), "UTF-8");
// 獲取最後一行 驗證是取得成功
String str = logs.get(logs.size() - 1);
if (str.contains("success")) {
log.info("uploadFileByFtp success");
return true;
} else {
log.warn("uploadFileByFtp fail.");
return false;
}
} catch (Exception e) {
log.error("uploadFileByFtp exception:{}", e);
return false;
}
}
還有一種是獲取cmd下的紀錄檔,
public static boolean uploadFileByFtp3() {
Process pro = Runtime.getRuntime().exec("cmd /c " + "D:\\tool\\uploadFileByFtp.exe" + " " + path);
// 標準輸入流(必須寫在 waitFor 之前)
String inStr = readInputStream(proc.getInputStream());
// 標準錯誤流(必須寫在 waitFor 之前)
String errStr = readInputStream(proc.getErrorStream());
int retCode = proc.waitFor();
if(retCode == 0){
System.out.println("檔案上傳成功");
}
}
/**
* 讀取緩衝流inputstream,並返回
*/
public static String readInputStream(InputStream is){
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String s ;
StringBuilder sb = new StringBuilder();
while((s=br.readLine())!=null){
System.out.println(s);
sb.append(s);
}
return sb.toString();
}
往期精彩內容: