中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中Process與Runtime()的使用示例

發布時間:2021-06-09 09:52:56 來源:億速云 閱讀:205 作者:小新 欄目:開發技術

這篇文章主要介紹Java中Process與Runtime()的使用示例,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

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()流中的內容,這個就看調用的程序的處理了。

java Process執行cmd命令流阻塞處理

代碼如下:

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()的使用示例”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长宁区| 阿坝县| 兴仁县| 五常市| 图木舒克市| 镇原县| 焦作市| 吴江市| 乐至县| 白城市| 蓬莱市| 岳普湖县| 云浮市| 罗城| 信丰县| 福贡县| 桦川县| 平邑县| 屯昌县| 昌江| 黔东| 南涧| 西城区| 西乌珠穆沁旗| 大方县| 深水埗区| 清水县| 宁强县| 靖远县| 和硕县| 织金县| 大渡口区| 阜阳市| 永和县| 大姚县| 武宁县| 丰县| 安远县| 哈密市| 卢氏县| 平原县|