Java執(zhí)行可執(zhí)行文件的三種方法詳解
概要
java執(zhí)行bat或shell腳本的方式主要有三種方式
1、 使用Runtime.exec
2、 使用ProcessBuilder
3、 使用第三方的工具包c(diǎn)ommons-exec.jar
使用Runtime.exec
在 Java 中,使用 Runtime.exec() 方法執(zhí)行外部可執(zhí)行文件是一個(gè)常見的做法。但是,這種方法有一些限制和潛在的問題,比如它不太容易處理進(jìn)程的輸入/輸出流。
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 提供了更強(qiáng)大和靈活的功能,并允許你更好地控制進(jìn)程的執(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);
使用第三方工具包c(diǎn)ommons-exec.jar
commons-exec.jar 是 Apache Commons Exec 庫的一部分,它提供了一個(gè)更強(qiáng)大和靈活的 API 來執(zhí)行外部進(jìn)程。與 Java 的標(biāo)準(zhǔn) Runtime.exec() 和 ProcessBuilder 類相比,Apache Commons Exec 提供了更多的功能和更好的錯(cuò)誤處理。
使用 Apache Commons Exec,你可以更容易地管理進(jìn)程執(zhí)行,包括設(shè)置進(jìn)程的工作目錄、環(huán)境變量、輸入/輸出流重定向、超時(shí)處理等。此外,它還提供了更好的錯(cuò)誤消息和異常處理,幫助開發(fā)者更容易地診斷問題。
要使用 commons-exec.jar,你需要將其添加到你的項(xiàng)目依賴中。如果你使用 Maven,你可以在 pom.xml 文件中添加以下依賴:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>1.3</version> <!-- 使用你需要的版本號(hào) -->
</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]:返回的警告或錯(cuò)誤信息
* @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分鐘超時(shí)
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)文章
Springboot+MyBatis進(jìn)行日志輸出參考示例
這篇文章主要給大家介紹了關(guān)于Springboot+MyBatis進(jìn)行日志輸出的相關(guān)資料,在項(xiàng)目開發(fā)過程中,日志是必不可少的,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
Java中Stream的flatMap與map使用場景及區(qū)別詳解
這篇文章主要介紹了Java中Stream的flatMap與map使用場景及區(qū)別詳解,Stream 流式操作,一般用于操作集合即 List 一類的數(shù)據(jù)結(jié)構(gòu),簡單來說 Stream 的 map 使得其中的元素轉(zhuǎn)為另一種元素的映射(map)方法,需要的朋友可以參考下2024-01-01
SpringBoot項(xiàng)目中jar發(fā)布獲取jar包所在目錄路徑的最佳方法
在開發(fā)過程中,我們經(jīng)常要遇到上傳圖片、word、pdf等功能,但是當(dāng)我們把項(xiàng)目打包發(fā)布到服務(wù)器上時(shí),對應(yīng)的很多存儲(chǔ)路徑的方法就會(huì)失效,下面這篇文章主要給大家介紹了關(guān)于SpringBoot項(xiàng)目中jar發(fā)布獲取jar包所在目錄路徑的相關(guān)資料2022-07-07
Java實(shí)體類實(shí)現(xiàn)鏈?zhǔn)讲僮鲗?shí)例解析
這篇文章主要介紹了Java實(shí)體類實(shí)現(xiàn)鏈?zhǔn)讲僮鲗?shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
SpringBoot Import及自定義裝配實(shí)現(xiàn)方法解析
這篇文章主要介紹了SpringBoot Import及自定義裝配實(shí)現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08

