Java執(zhí)行可執(zhí)行文件的三種方法詳解
概要
java執(zhí)行bat或shell腳本的方式主要有三種方式
1、 使用Runtime.exec
2、 使用ProcessBuilder
3、 使用第三方的工具包commons-exec.jar
使用Runtime.exec
在 Java 中,使用 Runtime.exec() 方法執(zhí)行外部可執(zhí)行文件是一個常見的做法。但是,這種方法有一些限制和潛在的問題,比如它不太容易處理進程的輸入/輸出流。
import java.io.IOException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 類名稱: ExeRunUtil. * 類描述: 執(zhí)行cmd命令 */ public class ExeRunUtil{ private static Log log = LogFactory.getLog(ExeRunUtil.class); /** * 執(zhí)行cmd命令 * @return 執(zhí)行結(jié)果 */ public static boolean exec(String[] command) { Process proc; try { proc = Runtime.getRuntime().exec(command); new StreamReader(proc,proc.getInputStream(),"Output" ).start(); new StreamReader(proc,proc.getErrorStream(),"Error").start(); } catch (IOException ex) { log.error("IOException while trying to execute " + command,ex); return false; } int exitStatus=1; try { exitStatus = proc.waitFor(); //等待操作完成 } catch (java.lang.InterruptedException ex) { log.error("InterruptedException command: " + exitStatus,ex); } if (exitStatus != 0) { log.error("Error executing command: " + exitStatus); } return (exitStatus == 0); } } import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * 獲取exe執(zhí)行信息 * @author shandongwill * */ public class StreamReader extends Thread{ private final Log logger = LogFactory.getLog(getClass()); private InputStream is; private String type; private Process proc; public StreamReader(Process proc,InputStream is, String type) { this.is = is; this.type = type; this.proc=proc; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { if (type.equals("Error")) { logger.error("Error:" + line); proc.destroyForcibly(); } else { logger.debug("Debug:" + line); } } } catch (IOException ioe) { logger.error(ioe); } } }
使用ProcessBuilder
相比于 Runtime.exec(),ProcessBuilder 提供了更強大和靈活的功能,并允許你更好地控制進程的執(zhí)行。
ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "test.bat"); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); int exitCode = process.waitFor(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } System.out.println("Exit code: " + exitCode);
使用第三方工具包commons-exec.jar
commons-exec.jar 是 Apache Commons Exec 庫的一部分,它提供了一個更強大和靈活的 API 來執(zhí)行外部進程。與 Java 的標(biāo)準(zhǔn) Runtime.exec() 和 ProcessBuilder 類相比,Apache Commons Exec 提供了更多的功能和更好的錯誤處理。
使用 Apache Commons Exec,你可以更容易地管理進程執(zhí)行,包括設(shè)置進程的工作目錄、環(huán)境變量、輸入/輸出流重定向、超時處理等。此外,它還提供了更好的錯誤消息和異常處理,幫助開發(fā)者更容易地診斷問題。
要使用 commons-exec.jar,你需要將其添加到你的項目依賴中。如果你使用 Maven,你可以在 pom.xml 文件中添加以下依賴:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-exec</artifactId> <version>1.3</version> <!-- 使用你需要的版本號 --> </dependency>
import java.io.ByteArrayOutputStream; import java.io.IOException; import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteException; import org.apache.commons.exec.ExecuteWatchdog; import org.apache.commons.exec.PumpStreamHandler; /** * CMD工具類 * * @author Administrator * */ public class CmdUtils { /** * 執(zhí)行命令 * * @param command:命令 * @return String[]數(shù)組,String[0]:返回的正常信息;String[1]:返回的警告或錯誤信息 * @throws ExecuteException * @throws IOException */ public static String[] handle(String command) throws ExecuteException, IOException { // 接收正常結(jié)果流 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 接收異常結(jié)果流 ByteArrayOutputStream errorStream = new ByteArrayOutputStream(); CommandLine commandline = CommandLine.parse(command); DefaultExecutor exec = new DefaultExecutor(); exec.setExitValues(null); // 設(shè)置10分鐘超時 ExecuteWatchdog watchdog = new ExecuteWatchdog(600 * 1000); exec.setWatchdog(watchdog); PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, errorStream); exec.setStreamHandler(streamHandler); exec.execute(commandline); // 不同操作系統(tǒng)注意編碼,否則結(jié)果亂碼 String out = outputStream.toString("UTF-8"); String error = errorStream.toString("UTF-8"); // 返回信息 String[] result = new String[2]; result[0] = out; result[1] = error; return result; } }
到此這篇關(guān)于Java執(zhí)行可執(zhí)行文件的三種方法詳解的文章就介紹到這了,更多相關(guān)Java執(zhí)行可執(zhí)行文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 反射修改類的常量值、靜態(tài)變量值、屬性值實例詳解
在本篇文章里小編給大家整理的是一篇關(guān)于Java 反射修改類的常量值、靜態(tài)變量值、屬性值實例詳解內(nèi)容,有興趣的讀者們可以跟著學(xué)習(xí)下。2021-01-01IDEA使用SequenceDiagram插件繪制時序圖的方法
這篇文章主要介紹了IDEA使用SequenceDiagram插件繪制時序圖的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Java class文件格式之特殊字符串_動力節(jié)點Java學(xué)院整理
特殊字符串出現(xiàn)在class文件中的常量池中,本著循序漸進和減少跨度的原則, 首先把class文件中的特殊字符串做一個詳細(xì)的介紹, 然后再回過頭來繼續(xù)講解常量池,對java class 文件格式相關(guān)知識感興趣的的朋友一起學(xué)習(xí)吧2017-06-06Java中FilterInputStream和FilterOutputStream的用法詳解
這篇文章主要介紹了Java中FilterInputStream和FilterOutputStream的用法詳解,這兩個類分別用于封裝輸入和輸出流,需要的朋友可以參考下2016-06-06