最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java Process與Runtime()的使用及調(diào)用cmd命令阻塞的解決方案

 更新時間:2021年06月08日 17:24:10   作者:Missmiaomiao  
這篇文章主要介紹了Java Process與Runtime()的使用及調(diào)用cmd命令阻塞的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Java Process與Runtime()使用

java調(diào)用cmd執(zhí)行bat文件有時會出現(xiàn)卡死的現(xiàn)象,當時感覺很迷惑,后來查資料,本來一般都是這樣來調(diào)用程序并獲取進程的輸出流的,但是我在windows上執(zhí)行這樣的調(diào)用的時候卻總是在while那里被堵塞了,結(jié)果造成ffmpeg程序在執(zhí)行了一會后不再執(zhí)行,這里從官方的參考文檔中我們可以看到這是由于緩沖區(qū)的問題,由于java進程沒有清空ffmpeg程序?qū)懙骄彌_區(qū)的內(nèi)容,結(jié)果導致ffmpeg程序一直在等待。

在網(wǎng)上也查找了很多這樣的問題,不過說的都是使用單獨的線程來進行控制,我也嘗試過很多網(wǎng)是所說的方法,可一直沒起什么作用。

一直認為是getInputStream的緩沖區(qū)沒有被清空,不過問題確實是緩沖區(qū)的內(nèi)容沒有被清空,但不是getInputStream的,而是getErrorStream的緩沖區(qū),這樣問題就得到解決了。

所以我們在遇到java調(diào)用外部程序而導致線程阻塞的時候,可以考慮使用兩個線程來同時清空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()的緩沖區(qū)
            InputStream is2 = process.getErrorStream();
            BufferedReader br2 = new BufferedReader(new InputStreamReader(is2)); 
            StringBuilder buf = new StringBuilder(); // 保存輸出結(jié)果流
            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()的輸出流,這樣我們就可以保證緩沖區(qū)得到及時的清空而不擔心線程被阻塞了。

當然根據(jù)需要你也可以保留process.getInputStream()流中的內(nèi)容,這個就看調(diào)用的程序的處理了。

java Process執(zhí)行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();
                }
            }
        }
    }
}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • SpringBoot自定義內(nèi)容協(xié)商的實現(xiàn)

    SpringBoot自定義內(nèi)容協(xié)商的實現(xiàn)

    在Spring Boot中,內(nèi)容協(xié)商是一種機制,它允許服務器根據(jù)客戶端的請求選擇返回不同的表示形式,本文就來詳細的介紹一下SpringBoot自定義內(nèi)容協(xié)商的實現(xiàn),感興趣的可以了解一下
    2024-09-09
  • Spring Cloud負載均衡及遠程調(diào)用實現(xiàn)詳解

    Spring Cloud負載均衡及遠程調(diào)用實現(xiàn)詳解

    這篇文章主要介紹了Spring Cloud負載均衡及遠程調(diào)用實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Java擴展Nginx之共享內(nèi)存

    Java擴展Nginx之共享內(nèi)存

    這篇文章主要介紹了Java擴展Nginx之共享內(nèi)存的相關資料,需要的朋友可以參考下
    2023-07-07
  • mybatis-plus支持null字段全量更新的兩種方法

    mybatis-plus支持null字段全量更新的兩種方法

    本文主要介紹了mybatis-plus支持null字段全量更新的兩種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • java多線程編程之使用Synchronized關鍵字同步類方法

    java多線程編程之使用Synchronized關鍵字同步類方法

    JAVA中要想解決“臟數(shù)據(jù)”的問題,最簡單的方法就是使用synchronized關鍵字來使run方法同步,看下面的代碼,只要在void和public之間加上synchronized關鍵字
    2014-01-01
  • Java動態(tài)替換properties文件中鍵值方式

    Java動態(tài)替換properties文件中鍵值方式

    這篇文章主要介紹了Java動態(tài)替換properties文件中鍵值方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 最新評論

    临沧市| 清徐县| 奈曼旗| 韶关市| 柯坪县| 丹东市| 六安市| 临清市| 兰州市| 南皮县| 溧阳市| 石河子市| 门头沟区| 廉江市| 琼海市| 常宁市| 垦利县| 定结县| 吉林市| 东辽县| 万山特区| 上饶市| 五原县| 来凤县| 九江县| 资源县| 上杭县| 历史| 岚皋县| 恭城| 大姚县| 揭西县| 泰顺县| 奇台县| 霞浦县| 丰顺县| 汉沽区| 巴林左旗| 赤城县| 景东| 新安县|