一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java程序執行Cmd指令所遇問題記錄及解決方案

Java程序執行Cmd指令所遇問題記錄及解決方案

2020-09-12 00:40BingoZe Java教程

這篇文章主要介紹了Java程序執行Cmd指令所遇問題記錄,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

這篇是有關在編寫Java程序執行Cmd指令時所遇到的問題記錄,其中有一些是個人的理解,如有問題望不吝賜教,感謝

Windows 命令提示符(cmd.exe)是 Windows NT 下的一個用于運行 Windows 控制面板程序或某些 DOS 程序的shell程序

1.執行Cmd命令的兩種方式

(1)RunTime.getRunTime().exec(多種重載方式) - 會得到一個Process對象通過其start()方法開啟一個新進程以執行輸入的指令。

Java程序執行Cmd指令所遇問題記錄及解決方案

這種方法就不多說了,最后這種形式還是用到第二種方式的方法(Java Api文檔中也推薦使用第二種方式去創建一個Process對象):

Java程序執行Cmd指令所遇問題記錄及解決方案

* @see ProcessBuilder
* @since 1.3
*/
public Process exec(String[] cmdarray, String[] envp, File dir)
throws IOException {
return new ProcessBuilder(cmdarray)
.environment(envp)
.directory(dir)
.start();
}

(2).new ProcessBuilder().command(指令)

2.獲取執行指令后的輸出:

Java程序執行Cmd指令所遇問題記錄及解決方案

在這里就遇到點問題,

上面兩種方式執行Windows自帶的命令都沒有什么問題(像Ping、Ipconfig)。但是當執行像“Java -version”這樣的外部命令,其輸出通過getInputStream()方法是拿不到的。

后來是通過參考網上資料,采用將子進程的輸出重定向到文件中,再從文件中讀取內容的方法:

// 外部程序的輸出放到了錯誤信息輸出流中,不將錯誤信息流輸出到文件話,輸出信息就看不到了
      pb.redirectErrorStream(true);
      // 把執行結果輸出
      pb.redirectOutput(file);
      //等待語句執行完成,否則可能會讀不到結果。
      pb.start().waitFor();
      InputStream in = new FileInputStream(file);
      br = new BufferedReader(new InputStreamReader(in,charsetName));
      String line = null;
      while ((line = br.readLine()) != null) {
        outPutResult.append(line).append("\n");
      }
      br.close();
      br = null;
      // 刪除臨時文件
      file.delete();

最新解決方法:剛寫完這篇博客,就在想Java開發文檔中這句“否則,如果使用ProcessBuilder.redirectErrorStream重定向子進程的標準錯誤,則此方法返回的輸入流將接收合并的標準輸出和子進程的標準錯誤。”(下面圖片)怎么就沒用呢,結果回頭一看,文檔是Java 8的,我跑的程序用的是Java 7的,把自己整笑了,還在這一通瞎操作。
而至于為什么要將子進程標準輸出和子進程的標準錯誤輸出合并,可以看下小弟下面的拙見。

對于非Windows自帶命令,可以這樣寫(不再需要借助文件):

public static StringBuilder runOutCmdTest(String command) {
    BufferedReader br = null;
    StringBuilder outPutResult = new StringBuilder();
    try{
    ProcessBuilder pb = new ProcessBuilder().command("cmd.exe", "/c", command);
    // 外部程序的輸出放到了錯誤信息輸出流中
    pb.redirectErrorStream(true);
    // 等待語句執行完成,否則可能會讀不到結果。
    Process process = pb.start();
    process.waitFor();
    InputStream inputStream = process.getInputStream();
    br = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
    String line;
    while ((line = br.readLine()) != null) {
      outPutResult.append(line).append("\n");
    }
    br.close();
    br = null;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return outPutResult;
  }

3.關于getInputStream ()無法得到子進程輸出的原因

Java程序執行Cmd指令所遇問題記錄及解決方案

此方法獲取的流是子進程正常輸出流不包括異常錯誤信息流,Process對象將異常信息放在了ErrorStream中。這里可以試一下,會發現執行“Java -version”控制臺輸出的是紅字,也就是異常信息。

Java程序執行Cmd指令所遇問題記錄及解決方案

emmm至于為什么Windows自帶命令的正常輸出會被視作異常信息,不太清楚,下次再looklook源碼。

而按上面圖片的最后一句,

4.一個調用指令例子

private static final String TEMP_FILE_PATH = "D:\\temp.txt";

  /**
   * 運行外部程序命令 無參數時調用
   * @param command 輸入命令
   * @return 輸出內容
   */
  public static StringBuilder runOutCmd(String command) {
    // 默認字符解析GBK
    return runOutCmd(command, null,"GBK");
  }

  /**
   * 運行外部程序命令 帶參數
   * @param command 輸入命令
   * @param args 輸入參數
   * @return
   */
  public static StringBuilder runOutCmd(String command, List<String> args) {
    // 默認字符解析GBK
    return runOutCmd(command, args,"GBK");
  }

  /**
   * 運行外部程序命令 - 帶參數并規定字符解析格式
   * @param args 輸入參數
   * @param command 輸入命令
   * @param charsetName 輸出字符解析格式
   * @return
   */
  public static StringBuilder runOutCmd(String command, List<String> args, String charsetName) {
    BufferedReader br = null;
    StringBuilder outPutResult = new StringBuilder();
    try {
      // 新建一個用來存儲子進程輸出結果結果的緩存文件
      File file = new File(TEMP_FILE_PATH);
      if (!file.getParentFile().exists()) {
        file.getParentFile().mkdirs();
      }
      if (!file.exists()) {
        file.createNewFile();
      }
      List<String> execCommand = new LinkedList<>();
      if (args != null) {
        execCommand.addAll(args);
      }
      execCommand.add(0,command);
      execCommand.add(0,"/c");
      execCommand.add(0,"cmd.exe");
      ProcessBuilder pb = new ProcessBuilder().command(execCommand).inheritIO();
      // 外部程序的輸出放到了錯誤信息輸出流中
      pb.redirectErrorStream(true);
      // 把執行結果輸出
      pb.redirectOutput(file);
      //等待語句執行完成,否則可能會讀不到結果。
      pb.start().waitFor();
      InputStream in = new FileInputStream(file);
      br = new BufferedReader(new InputStreamReader(in,charsetName));
      String line = null;
      while ((line = br.readLine()) != null) {
        outPutResult.append(line).append("\n");
      }
      br.close();
      br = null;
      // 刪除臨時文件
      file.delete();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (br != null) {
        try {
          br.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    return outPutResult;
  }

最新例子(不用借助文件):

/**
 * 運行外部程序命令 - 帶參數并規定字符解析格式
 *
 * @param args    輸入參數
 * @param command   輸入命令
 * @param charsetName 輸出字符解析格式
 * @return
 */
public static StringBuilder runOutCmd(String command, List<String> args, String charsetName) {
  BufferedReader br = null;
  StringBuilder outPutResult = new StringBuilder();
  try {
    List<String> execCommand = new LinkedList<>();
    if (args != null) {
      execCommand.addAll(args);
    }
    execCommand.add(0, command);
    execCommand.add(0, "/c");
    execCommand.add(0, "cmd.exe");
    ProcessBuilder pb = new ProcessBuilder().command(execCommand).inheritIO();
    // 外部程序的輸出放到了錯誤信息輸出流中
    pb.redirectErrorStream(true);
    //等待語句執行完成,否則可能會讀不到結果。
    Process process = pb.start();
    process.waitFor();
    InputStream inputStream = process.getInputStream();
    br = new BufferedReader(new InputStreamReader(inputStream, charsetName));
    String line;
    while ((line = br.readLine()) != null) {
      outPutResult.append(line).append("\n");
    }
    br.close();
    br = null;
  } catch (Exception e) {
    e.printStackTrace();
  } finally {
    if (br != null) {
      try {
        br.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  return outPutResult;
}

ps:
1. inheritIO()作用:

Java程序執行Cmd指令所遇問題記錄及解決方案

意味著使用此方法,子進程的報錯的異常信息也會在當前Java進程的控制臺輸出,而Process對象將非Windows命令的輸出視為異常信息,那么非Windows命令的輸出當使用了此方法的時候會在控制臺輸出。

2.字符解析格式問題:
輸出出現亂碼,與Cmd程序字符格式默認為GBK有關。
按實際情況修改流的解析格式就可以了:

 br = new BufferedReader(new InputStreamReader(in,charsetName));

Java程序執行Cmd指令所遇問題記錄及解決方案

到此這篇關于Java程序執行Cmd指令所遇問題記錄及解決方案的文章就介紹到這了,更多相關Java程序執行Cmd指令內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_42882845/article/details/108520470

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 免费看打屁股视频的软件 | 日本-区二区三区免费精品 日本破处 | tobu8在线观看免费高清 | 四虎精品永久在线网址 | 国产一区二区视频在线播放 | 猫咪免费人成网站在线观看入口 | 4444亚洲国产成人精品 | 日日摸日日添日日透 | 成人中文字幕在线观看 | 国产成人咱精品视频免费网站 | 精品国产品香蕉在线观看 | 国产精品原创视频 | 男人捅女人漫画 | 国产在线拍 | 99精品视频免费观看 | 精品国产成人AV在线看 | 亚洲国产成人精品激情 | 国产综合久久 | 国产成+人+综合+欧美 亚洲 | 午夜香蕉成视频人网站高清版 | www.青草视频 | 国内久久精品视频 | 高清麻生希在线 | 欧美丝袜videohd | 国产日韩视频一区 | 大伊人青草狠狠久久 | 亚洲成人一区二区 | 亚洲 欧美 国产 日韩 字幕 | 亚洲成熟人网站 | 欧式午夜理伦三级在线观看 | 呜嗯啊野战h呻吟男男双性 污小说在线阅读 | 人人爱天天做夜夜爽88 | 免费在线观看成年人视频 | 成人影院在线看 | 奇米7777第四色 | 亚洲欧美日韩另类在线 | 亚洲天堂视频在线播放 | 被黑人同学彻底征服全文小说阅读 | 国产51社区精品视频资源 | 日韩经典在线观看 | 亚洲国产成人久久综合一区 |