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

java如何執(zhí)行l(wèi)inux/cmd命令

 更新時(shí)間:2026年01月04日 10:05:12   作者:夏子曦  
本文詳細(xì)介紹了在Java中執(zhí)行命令行命令的兩種方法:Runtime.exec()和ProcessBuilder,包括它們的優(yōu)缺點(diǎn)、參數(shù)傳遞、流處理、多線程處理、超時(shí)控制、跨平臺(tái)兼容性和亂碼問(wèn)題的解決方案

在Java中執(zhí)行命令行命令可以通過(guò)Runtime.exec()ProcessBuilder實(shí)現(xiàn)。以下是兩種方法的詳細(xì)說(shuō)明和示例代碼:

使用Runtime.exec()

適用于簡(jiǎn)單場(chǎng)景,但需手動(dòng)處理輸入/輸出流。

try {
    // 執(zhí)行命令(參數(shù)以數(shù)組形式傳遞,避免空格問(wèn)題)
    Process process = Runtime.getRuntime().exec(new String[]{"ping", "-n", "3", "127.0.0.1"});
    
    // 讀取標(biāo)準(zhǔn)輸出流
    BufferedReader inputReader = new BufferedReader(
        new InputStreamReader(process.getInputStream())
    );
    // 讀取錯(cuò)誤流
    BufferedReader errorReader = new BufferedReader(
        new InputStreamReader(process.getErrorStream())
    );
    
    // 打印輸出和錯(cuò)誤信息
    String line;
    while ((line = inputReader.readLine()) != null) {
        System.out.println("輸出: " + line);
    }
    while ((line = errorReader.readLine()) != null) {
        System.out.println("錯(cuò)誤: " + line);
    }
    
    // 等待命令執(zhí)行完成并獲取退出碼
    int exitCode = process.waitFor();
    System.out.println("退出碼: " + exitCode);
    
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

使用ProcessBuilder

更靈活,支持錯(cuò)誤流合并、工作目錄設(shè)置等。

try {
    // 構(gòu)建命令及參數(shù)
    ProcessBuilder pb = new ProcessBuilder();
    pb.command("ping", "-n", "3", "127.0.0.1");
    
    // 合并標(biāo)準(zhǔn)輸出和錯(cuò)誤流(簡(jiǎn)化處理)
    pb.redirectErrorStream(true);
    
    // 設(shè)置工作目錄(可選)
    // pb.directory(new File("path/to/dir"));
    
    // 啟動(dòng)進(jìn)程
    Process process = pb.start();
    
    // 讀取輸出流
    BufferedReader reader = new BufferedReader(
        new InputStreamReader(process.getInputStream())
    );
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
    
    // 等待命令結(jié)束
    int exitCode = process.waitFor();
    System.out.println("退出碼: " + exitCode);
    
} catch (IOException | InterruptedException e) {
    e.printStackTrace();
}

關(guān)鍵點(diǎn)說(shuō)明

參數(shù)傳遞

將命令和參數(shù)拆分為字符串?dāng)?shù)組,避免空格導(dǎo)致的解析錯(cuò)誤。

流處理

  • 必須讀取輸出流:否則進(jìn)程可能因緩沖區(qū)滿而阻塞。
  • 多線程處理:若需同時(shí)處理標(biāo)準(zhǔn)輸出和錯(cuò)誤流,可使用多線程(如示例1)。
  • 合并流:通過(guò)redirectErrorStream(true)合并錯(cuò)誤流到標(biāo)準(zhǔn)輸出,簡(jiǎn)化代碼(如示例2)。

超時(shí)控制

使用waitFor(long timeout, TimeUnit unit)(Java 8+)防止無(wú)限等待:

if (!process.waitFor(30, TimeUnit.SECONDS)) {
    process.destroy(); // 強(qiáng)制終止進(jìn)程
    System.out.println("命令執(zhí)行超時(shí)");
}

跨平臺(tái)兼容性

  • Windows可能需要cmd /c前綴:
pb.command("cmd", "/c", "dir");
  • 根據(jù)系統(tǒng)屬性調(diào)整命令:
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
    pb.command("cmd", "/c", "mycommand");
} else {
    pb.command("sh", "-c", "mycommand");
}

資源釋放

finally塊中關(guān)閉流或使用Try-with-Resources(需自定義處理)。

亂碼

在Java中讀取命令行輸出時(shí)出現(xiàn)中文亂碼,通常是因?yàn)?strong>系統(tǒng)默認(rèn)編碼與命令行輸出的編碼不一致(例如,Windows的cmd默認(rèn)使用GBK編碼,而程序可能使用UTF-8)。

以下是解決方案及優(yōu)化后的代碼:

原因分析

  • Windows命令行編碼:默認(rèn)使用GBK(對(duì)應(yīng)代碼頁(yè)CP936)。
  • Linux/macOS終端編碼:通常為UTF-8
  • Java程序默認(rèn)編碼:可能與系統(tǒng)編碼不同(例如,IDE運(yùn)行時(shí)默認(rèn)UTF-8)。

解決方案

1.顯式指定字符編碼

在創(chuàng)建InputStreamReader時(shí),明確指定與命令行輸出一致的編碼(如Windows下使用GBK)。

// Windows示例:使用GBK編碼讀取
BufferedReader inputReader = new BufferedReader(
    new InputStreamReader(process.getInputStream(), "GBK")
);

// Linux/macOS示例:使用UTF-8
BufferedReader inputReader = new BufferedReader(
    new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)
);

2.自動(dòng)檢測(cè)系統(tǒng)編碼(推薦)

動(dòng)態(tài)判斷操作系統(tǒng)類型,自動(dòng)選擇編碼:

import java.nio.charset.Charset;

public class CharsetHelper {
    // 獲取命令行輸出的默認(rèn)編碼(Windows為GBK,其他系統(tǒng)為UTF-8)
    public static Charset getConsoleCharset() {
        String os = System.getProperty("os.name").toLowerCase();
        if (os.contains("win")) {
            return Charset.forName("GBK");
        } else {
            return StandardCharsets.UTF_8;
        }
    }
}

// 使用示例:
Charset charset = CharsetHelper.getConsoleCharset();
BufferedReader inputReader = new BufferedReader(
    new InputStreamReader(process.getInputStream(), charset)
);

完整優(yōu)化代碼示例(以ProcessBuilder為例)

import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) {
        //System.out.println("Hello, World!");
        RuntimeExec("ping 127.0.0.1");
        RuntimeExec2("ping www.baidu.com");
    }

    public static void RuntimeExec(String cmd) {
        try {
            if (StringUtils.isBlank(cmd)) {
                return;
            }
            String[] cmds = cmd.split(" ");
            // 出去空格
            for (int i = 0; i < cmds.length; i++)
                cmds[i] = cmds[i].trim();
            // 執(zhí)行命令(參數(shù)以數(shù)組形式傳遞,避免空格問(wèn)題)
            Process process = Runtime.getRuntime().exec(cmds); /*, null, new File("C:\\Windows\\System32")*/  //new String[]{"ping", "-n", "3", "127.0.0.1"});

            // 讀取標(biāo)準(zhǔn)輸出流
            BufferedReader inputReader = new BufferedReader(
                    new InputStreamReader(process.getInputStream(), "GB2312")
            );
            // 讀取錯(cuò)誤流
            BufferedReader errorReader = new BufferedReader(
                    new InputStreamReader(process.getErrorStream(), "GB2312")
            );

            // 打印輸出和錯(cuò)誤信息
            String line;
            while ((line = inputReader.readLine()) != null) {
                System.out.println("out: " + line);
            }
            while ((line = errorReader.readLine()) != null) {
                System.out.println("err: " + line);
            }

            // 等待命令執(zhí)行完成并獲取退出碼
            int exitCode = process.waitFor();
            System.out.println("out: " + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void RuntimeExec2(String cmd) {
        try {
            if (StringUtils.isBlank(cmd)) {
                return;
            }
            String[] cmds = cmd.split(" ");
            // 出去空格
            for (int i = 0; i < cmds.length; i++)
                cmds[i] = cmds[i].trim();
            // 構(gòu)建命令及參數(shù)
            ProcessBuilder pb = new ProcessBuilder();
            pb.command(cmds);

            // 合并標(biāo)準(zhǔn)輸出和錯(cuò)誤流(簡(jiǎn)化處理)
            pb.redirectErrorStream(true);

            // 設(shè)置工作目錄(可選)
            // pb.directory(new File("path/to/dir"));

            // 啟動(dòng)進(jìn)程
            Process process = pb.start();

            // 讀取輸出流
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream(),"GB2312")
            );
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }

            // 等待命令結(jié)束
            int exitCode = process.waitFor();
            System.out.println("退出碼: " + exitCode);

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

其他注意事項(xiàng)

強(qiáng)制命令行使用UTF-8(Windows)

在Windows中,可以通過(guò)/U參數(shù)讓cmd輸出UTF-8編碼:

pb.command("cmd", "/U", "/c", "chcp 65001 && ping -n 3 127.0.0.1");

此時(shí)需將編碼設(shè)置為UTF-8

new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)

驗(yàn)證命令行編碼

Windows下運(yùn)行chcp命令查看活動(dòng)代碼頁(yè):

  • 936GBK
  • 65001UTF-8

根據(jù)實(shí)際代碼頁(yè)調(diào)整編碼設(shè)置。

統(tǒng)一環(huán)境編碼

在程序啟動(dòng)時(shí)指定JVM編碼(如-Dfile.encoding=UTF-8),但需確保與命令行編碼一致。

總結(jié)

  • 簡(jiǎn)單命令:推薦ProcessBuilder,代碼更簡(jiǎn)潔。
  • 復(fù)雜場(chǎng)景(如交互式輸入、大量輸出):結(jié)合多線程處理流,避免阻塞。
  • 注意事項(xiàng):正確處理參數(shù)、流、超時(shí)及跨平臺(tái)問(wèn)題。

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

相關(guān)文章

  • Java語(yǔ)言字典序排序算法解析及代碼示例

    Java語(yǔ)言字典序排序算法解析及代碼示例

    這篇文章主要介紹了Java語(yǔ)言字典序排序算法解析及代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • MyBatisPlus超詳細(xì)分析條件查詢

    MyBatisPlus超詳細(xì)分析條件查詢

    這篇文章主要介紹了MyBatisPlus條件查詢的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • JavaSE、JavaEE和JavaWeb三大工程目錄詳解

    JavaSE、JavaEE和JavaWeb三大工程目錄詳解

    這篇文章主要給大家介紹了關(guān)于JavaSE、JavaEE和JavaWeb三大工程目錄的相關(guān)資料,很多對(duì)java不是很了解的同學(xué)在看到課程?綱的時(shí)候發(fā)現(xiàn)??出現(xiàn)了JavaSE、JavaEE、JavaME、JavaWEB這些詞,搞得?頭霧?,需要的朋友可以參考下
    2023-07-07
  • 解決SpringBoot返回結(jié)果如果為null或空值不顯示處理問(wèn)題

    解決SpringBoot返回結(jié)果如果為null或空值不顯示處理問(wèn)題

    這篇文章主要介紹了解決SpringBoot返回結(jié)果如果為null或空值不顯示處理問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java將字節(jié)轉(zhuǎn)換為十六進(jìn)制代碼分享

    Java將字節(jié)轉(zhuǎn)換為十六進(jìn)制代碼分享

    我們知道,在java中,一個(gè)byte 就是一個(gè)字節(jié),也就是八個(gè)二進(jìn)制位;而4個(gè)二進(jìn)制位就可以表示一個(gè)十六進(jìn)制位,所以一個(gè)byte可以轉(zhuǎn)化為2個(gè)十六進(jìn)制位。下面我們就來(lái)詳細(xì)看下具體方法吧。
    2016-01-01
  • Spring中OpenFeign的使用方法最佳實(shí)踐

    Spring中OpenFeign的使用方法最佳實(shí)踐

    這篇文章主要介紹了Spring中OpenFeign使用的相關(guān)資料,OpenFeign是一個(gè)聲明式的WebService客戶端,簡(jiǎn)化了微服務(wù)之間的調(diào)用,類似于Controller調(diào)用Service,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-02-02
  • 深入學(xué)習(xí)java位運(yùn)算的基礎(chǔ)知識(shí)

    深入學(xué)習(xí)java位運(yùn)算的基礎(chǔ)知識(shí)

    位運(yùn)算是直接對(duì)整數(shù)在內(nèi)存中的二進(jìn)制位進(jìn)行操作嗎,位運(yùn)算即可以節(jié)約內(nèi)存,同時(shí)使程序速度更快效率更高。文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,下面我們來(lái)一起學(xué)習(xí)下吧
    2019-06-06
  • JAVA中的 map,list,set

    JAVA中的 map,list,set

    這篇文章主要介紹了JAVA中的 map、list、set這三個(gè)集合,下面文章圍繞JAVA中的三大集合 map、list、set詳情講解,需要的朋友可以參考一下
    2021-11-11
  • java實(shí)現(xiàn)文件導(dǎo)入導(dǎo)出

    java實(shí)現(xiàn)文件導(dǎo)入導(dǎo)出

    這篇文章主要介紹了java實(shí)現(xiàn)文件導(dǎo)入導(dǎo)出的方法和具體示例代碼,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下
    2016-04-04
  • 淺談Java線程Thread.join方法解析

    淺談Java線程Thread.join方法解析

    本篇文章主要介紹了淺談Java線程Thread.join方法解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01

最新評(píng)論

张家口市| 临安市| 绥芬河市| 廊坊市| 莲花县| 东平县| 中超| 桐庐县| 宁明县| 杭州市| 伊金霍洛旗| 前郭尔| 丹凤县| 华宁县| 茌平县| 马尔康县| 新化县| 吉安市| 桦川县| 乌拉特中旗| 屯昌县| 雷波县| 沂源县| 安新县| 乐昌市| 集贤县| 沁水县| 赤水市| 新巴尔虎左旗| 南昌县| 西和县| 永登县| 肇东市| 阿坝| 滁州市| 马边| 余干县| 泸西县| 聊城市| 沁源县| 宜兴市|