您好,登錄后才能下訂單哦!
這篇文章主要介紹Java中Process與Runtime()的使用示例,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
java調用cmd執行bat文件有時會出現卡死的現象,當時感覺很迷惑,后來查資料,本來一般都是這樣來調用程序并獲取進程的輸出流的,但是我在windows上執行這樣的調用的時候卻總是在while那里被堵塞了,結果造成ffmpeg程序在執行了一會后不再執行,這里從官方的參考文檔中我們可以看到這是由于緩沖區的問題,由于java進程沒有清空ffmpeg程序寫到緩沖區的內容,結果導致ffmpeg程序一直在等待。
在網上也查找了很多這樣的問題,不過說的都是使用單獨的線程來進行控制,我也嘗試過很多網是所說的方法,可一直沒起什么作用。
一直認為是getInputStream的緩沖區沒有被清空,不過問題確實是緩沖區的內容沒有被清空,但不是getInputStream的,而是getErrorStream的緩沖區,這樣問題就得到解決了。
所以我們在遇到java調用外部程序而導致線程阻塞的時候,可以考慮使用兩個線程來同時清空process獲取的兩個輸入流,如下這段程序:
public String excuteBatFile(String file, boolean isCloseWindow) { String cmdCommand = null; String res = null; if(isCloseWindow) { cmdCommand = "cmd.exe /c " + file; }else { cmdCommand = "cmd.exe /k " + file; } StringBuilder stringBuilder = new StringBuilder(); Process process = null; try { process = Runtime.getRuntime().exec(cmdCommand); final InputStream is1 = process.getInputStream(); new Thread(new Runnable() { public void run() { BufferedReader bufferedReader = null; String line = null; try { bufferedReader = new BufferedReader( new InputStreamReader(is1, "GBK")); while((line=bufferedReader.readLine()) != null) { stringBuilder.append(line+"\n"); } is1.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); // 啟動單獨的線程來清空p.getInputStream()的緩沖區 InputStream is2 = process.getErrorStream(); BufferedReader br2 = new BufferedReader(new InputStreamReader(is2)); StringBuilder buf = new StringBuilder(); // 保存輸出結果流 String line2 = null; while((line2 = br2.readLine()) != null) buf.append(line2); // log.info("----res:----" + stringBuilder + "&" + buf); return stringBuilder + "&" + buf; } catch (Exception e) { e.printStackTrace(); return e.toString(); } }
通過這樣我們使用一個線程來讀取process.getInputStream()的輸出流,使用另外一個線程來獲取process.getErrorStream()的輸出流,這樣我們就可以保證緩沖區得到及時的清空而不擔心線程被阻塞了。
當然根據需要你也可以保留process.getInputStream()流中的內容,這個就看調用的程序的處理了。
代碼如下:
public static void runCmd() { Process process = null; BufferedReader bufferedReader = null; try { Logger.getLogger(SystemService.class).info("============= 開始重啟機器 ============="); process = Runtime.getRuntime().exec("cmd.exe /c shutdown -r -f -t 0"); bufferedReader = new BufferedReader(new InputStreamReader(new BufferedInputStream(process.getInputStream()), Charset.forName("GB2312"))); // 開啟線程讀取錯誤輸出,避免阻塞 new StreamInformatonThread(process.getErrorStream(), "error").start(); String outStr; while ((outStr = bufferedReader.readLine()) != null) { Logger.getLogger(SystemService.class).info("readLine -------> : " + outStr); } Logger.getLogger(SystemService.class).info("============= 重啟機器完成 ============="); } catch (IOException e) { Logger.getLogger(SystemService.class).error("============= 重啟機器失敗 ============="); e.printStackTrace(); } finally { if (process != null) { process.destroy(); } if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
import java.io.*; /** * @Description:流阻塞處理 * @Author: zhangwenchao * @Date: 2019/7/9 11:35 */ public class StreamInformatonThread extends Thread { private InputStream is; private String str; private Logger logger = Logger.getLogger(StreamInformatonThread.class); public StreamInformatonThread(InputStream is, String str) { this.is = is; this.str = str; } public void run() { BufferedReader out = null; try { out = new BufferedReader(new InputStreamReader(is, "gbk")); String line; while ((line = out.readLine()) != null) { if (str.equals("error")) { logger.info("ErrorStream --------> :" +line); } else { logger.info("outLine ---------> :" + line); } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
以上是“Java中Process與Runtime()的使用示例”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。