Java执行可执行文件的三种方法详解

 更新时间:2024年02月06日 14:00:27   作者:shandongwill  
这篇文章主要为大家详细介绍了Java中执行可执行文件的三种方法,文中的示例代码讲解详细,具有一定的借鉴价值,需要的小伙伴可以参考一下

概要

java执行bat或shell脚本的方式主要有三种方式

1、 使用Runtime.exec

2、 使用ProcessBuilder

3、 使用第三方的工具包commons-exec.jar

使用Runtime.exec

在 Java 中,使用 Runtime.exec() 方法执行外部可执行文件是一个常见的做法。但是,这种方法有一些限制和潜在的问题,比如它不太容易处理进程的输入/输出流。

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * 类名称: ExeRunUtil.
 * 类描述: 执行cmd命令
 */
public class ExeRunUtil{
	private static Log log = LogFactory.getLog(ExeRunUtil.class);
	 /** 
     * 执行cmd命令
     * @return 执行结果
     */  
    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执行信息
 * @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 提供了更强大和灵活的功能,并允许你更好地控制进程的执行。

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 来执行外部进程。与 Java 的标准 Runtime.exec() 和 ProcessBuilder 类相比,Apache Commons Exec 提供了更多的功能和更好的错误处理。

使用 Apache Commons Exec,你可以更容易地管理进程执行,包括设置进程的工作目录、环境变量、输入/输出流重定向、超时处理等。此外,它还提供了更好的错误消息和异常处理,帮助开发者更容易地诊断问题。

要使用 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 {
	/**
	 * 执行命令
	 * 
	 * @param command:命令
	 * @return String[]数组,String[0]:返回的正常信息;String[1]:返回的警告或错误信息
	 * @throws ExecuteException
	 * @throws IOException
	 */
	public static String[] handle(String command) throws ExecuteException, IOException {
		// 接收正常结果流
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		// 接收异常结果流
		ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
		CommandLine commandline = CommandLine.parse(command);
		DefaultExecutor exec = new DefaultExecutor();
		exec.setExitValues(null);
		// 设置10分钟超时
		ExecuteWatchdog watchdog = new ExecuteWatchdog(600 * 1000);
		exec.setWatchdog(watchdog);
		PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream, errorStream);
		exec.setStreamHandler(streamHandler);
		exec.execute(commandline);
		// 不同操作系统注意编码,否则结果乱码
		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;
	}
}

到此这篇关于Java执行可执行文件的三种方法详解的文章就介绍到这了,更多相关Java执行可执行文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • oracle+mybatis-plus+springboot实现分页查询的实例

    oracle+mybatis-plus+springboot实现分页查询的实例

    本文主要介绍了oracle+mybatis-plus+springboot实现分页查询,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • SpringBoot利用redis集成消息队列的方法

    SpringBoot利用redis集成消息队列的方法

    这篇文章主要介绍了SpringBoot利用redis集成消息队列的方法,需要的朋友可以参考下
    2017-08-08
  • 详解SpringMVC中拦截器的概念及入门案例

    详解SpringMVC中拦截器的概念及入门案例

    拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行。本文将详细讲讲SpringMVC中拦截器的概念及入门案例,感兴趣的可以尝试一下
    2022-07-07
  • Java中数组复制的三种方式小结

    Java中数组复制的三种方式小结

    在Java中,数组复制是一种常见的操作,它允许开发人员在不修改原始数组的情况下创建一个新的数组,本文就来介绍三种方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • 深入解析反编译字节码文件中的代码逻辑JVM中的String操作

    深入解析反编译字节码文件中的代码逻辑JVM中的String操作

    这篇文章主要介绍了深入解析反编译字节码文件中的代码逻辑JVM中的String操作,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Java虚拟机执行引擎知识总结

    Java虚拟机执行引擎知识总结

    这篇文章主要介绍了有关Java虚拟机执行引擎的知识,文中实例简单易懂,方便大家更好的学习,有兴趣的朋友可以了解下
    2020-06-06
  • Spring Boot实现模块化的几种方法

    Spring Boot实现模块化的几种方法

    模块可以是业务模块,为应用程序提供一些业务服务,或者为几个其他模块或整个应用程序提供跨领域关注的技术模块。这篇文章主要介绍了Spring Boot实现模块化,需要的朋友可以参考下
    2018-07-07
  • java 读取文件路径空格、

    java 读取文件路径空格、"+"和中文的处理方法

    今天小编就为大家分享一篇java 读取文件路径空格、"+"和中文的处理方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 一个例子带你看懂Java中synchronized关键字到底怎么用

    一个例子带你看懂Java中synchronized关键字到底怎么用

    synchronized是Java里的一个关键字,起到的一个效果是"监视器锁",它的功能就是保证操作的原子性,同时禁止指令重排序和保证内存的可见性,下面这篇文章主要给大家介绍了关于如何通过一个例子带你看懂Java中synchronized关键字到底怎么用的相关资料,需要的朋友可以参考下
    2022-10-10
  • Springboot中整合knife4j接口文档的过程详解

    Springboot中整合knife4j接口文档的过程详解

    knife4j就swagger的升级版API文档的一个框架,但是用起来比swagger方便多了,UI更加丰富,这篇文章主要介绍了Springboot中整合knife4j接口文档,需要的朋友可以参考下
    2022-04-04

最新评论