首页 > 系统相关 >使用java创建新的进程

使用java创建新的进程

时间:2024-03-16 13:57:45浏览次数:30  
标签:java String exec process 创建 new 进程 import

使用jdk内置的工具

import org.apache.commons.io.IOUtils;
import java.nio.charset.Charset;

public class TestProcess {
    public static void main(String[] args) throws Exception {
        testExec();
    }

    private static void testExec() throws Exception {
        String commandPath = "/bin/ls";
        String param = "/Users/xxx/testjars";

        String fullCommand = new StringBuilder()
                .append(commandPath)
                .append(" ")
                .append(param)
                .toString();
        Process process = Runtime.getRuntime().exec(fullCommand);
        int exitCode = process.waitFor();
        // 状态码0表示执行成功
        if (exitCode == 0) {
            String result = IOUtils.toString(process.getInputStream(), Charset.forName("GBK"));
            System.out.println(result);
        } else {
            String errMsg = IOUtils.toString(process.getErrorStream(), Charset.forName("GBK"));
            System.out.println(errMsg);
        }
    }

}

Runtime 的 exec() 方法内部会将完整命令使用 空格或者换行 分割为多个,第一个当作执行命令,后面的当作执行参数。内部使用 ProcessBuilder 来创建 Process。

import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

public class TestProcess2 {
    public static void main(String[] args) throws Exception {
        testExec();
    }

    private static void testExec() throws IOException, InterruptedException {
        String commandPath = "/bin/ls";
        String param = "/Users/xxx/testjars";
        List<String> commands = Arrays.asList(commandPath, param);
        Process process = new ProcessBuilder().command(commands).start();
        int exitCode = process.waitFor();
        // 状态码0表示执行成功
        if (exitCode == 0) {
            String result = IOUtils.toString(process.getInputStream(), Charset.forName("GBK"));
            System.out.println(result);
        } else {
            String errMsg = IOUtils.toString(process.getErrorStream(), Charset.forName("GBK"));
            System.out.println(errMsg);
        }
    }
}

和上面类似,直接使用 ProcessBuilder 来创建 Process。注意,这个时候,command() 方法不能直接传一个完整命令,如下所示

private static void testExec2() throws IOException, InterruptedException {
        String commandPath = "/bin/ls";
        String param = "/Users/xxx/testjars";

        String fullCommand = new StringBuilder()
                .append(commandPath)
                .append(" ")
                .append(param)
                .toString();
        List<String> commands = Arrays.asList(fullCommand);
        Process process = new ProcessBuilder().command(commands).start();
        int exitCode = process.waitFor();
        ...
    }

这种情况会报错

Exception in thread "main" java.io.IOException: Cannot run program "/bin/ls /Users/xxx/testjars": error=2, No such file or directory
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
	at com.imooc.TestProcess2.testExec2(TestProcess2.java:41)
	at com.imooc.TestProcess2.main(TestProcess2.java:12)
Caused by: java.io.IOException: error=2, No such file or directory
	at java.lang.UNIXProcess.forkAndExec(Native Method)
	at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
	at java.lang.ProcessImpl.start(ProcessImpl.java:134)
	at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
	... 2 more

它是把 完整命令当作 执行命令了,就会报找不到这个命令(/bin/ls /Users/xxx/testjars)。

使用apache的commons-exec工具

引入依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-exec</artifactId>
    <version>1.3</version>
</dependency>

代码如下

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.PumpStreamHandler;

import java.io.ByteArrayOutputStream;

public class TestCommonsExec {
    public static void main(String[] args) throws Exception {
        testExec();
    }

    private static void testExec() throws Exception {
        String commandPath = "/bin/ls";
        String param = "/Users/zzshi/szz_files/testjars";

        String fullCommand = new StringBuilder()
                .append(commandPath)
                .append(" ")
                .append(param)
                .toString();
        //接收正常结果流
        ByteArrayOutputStream susStream = new ByteArrayOutputStream();
        //接收异常结果流
        ByteArrayOutputStream errStream = new ByteArrayOutputStream();
        CommandLine commandLine = CommandLine.parse(fullCommand);
        DefaultExecutor exec = new DefaultExecutor();
        PumpStreamHandler streamHandler = new PumpStreamHandler(susStream, errStream);
        exec.setStreamHandler(streamHandler);
        int exitCode = exec.execute(commandLine);
        // 状态码0表示执行成功
        if (exitCode == 0) {
            String result = susStream.toString("GBK");
            System.out.println(result);
        } else {
            String errMsg = errStream.toString("GBK");
            System.out.println(errMsg);
        }
    }
}

使用 commons-exec 更加的方便,且支持异步、超时取消等更多功能,使用 ExecuteWatchdog 来实现超时取消(内部创建一个线程一直监听)。Watchdog也就是看门狗,Redission的分布式锁中也有相同的角色。

参考

程序员的福音 - Apache Commons Exec

标签:java,String,exec,process,创建,new,进程,import
From: https://www.cnblogs.com/strongmore/p/18048683

相关文章

  • 使用Anaconda创建Python指定版本的虚拟环境
    由于工作的需要和学习的需要,需要创建不同Python版本的虚拟环境。比如zdppy的框架,主要支持的是Python3.8的版本,但是工作中FastAPI主要使用的是3.11的版本,所以本地需要两套Python环境。决定使用Anaconda虚拟环境管理的能力,并记录下。首先,下载:https://www.anaconda.com/down......
  • Java学习笔记——第十七天
    File、IO流(一)为什么要有文件存储数据的方案变量、数组、内存和集合它们都是内存中的数据容器,这些数据在断电或程序终止时会丢失。文件文件是非常重要的存储方式。它们存储在计算机硬盘中,即便断电,或者程序终止了,存储在硬盘文件中的数据也不会丢失。File和IO流概述FileFil......
  • Java从8到21的语言新特性
    try-with-resource可以使用既有的变量//java9之前try(InputStreamis=Files.newInputStream(Paths.get("1111"))){//dosomething}//java9之后可以这样了InputStreamis=Files.newInputStream(Paths.get("1111"));try(is){//dosomething......
  • Java面试题(19)Java元注解之@Retention
    序言@Retention 注解是用来注解的注解,称为元注解,其作用可以简单理解为设置注解的生命周期。@Retention 注解传入的是 RetentionPolicy 枚举,该枚举有三个常量,分别是 SOURCE、CLASS 和 RUNTIME三者区别如下:SOURCE 代表着注解仅保留在源级别中,编译器将Java文件编译成cl......
  • 快速创建一个spring-boot-starter
    可以使用springspi和import两种方法1.导入starter依赖1.1.maven管理工具<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>1.2.gradle管理工......
  • java企业人事管理系统(ssm框架毕业设计)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义标题:企业人事管理系统的选题背景在现代企业管理中,人力资源作为企业最宝贵的资产之一,其管理效率和效果直接关系到企业的竞争力和发展潜力。传统的人力资源管理方式......
  • java企业日常事务管理系统(ssm框架毕业设计)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在现代商业环境中,企业的日常运营活动日益复杂多变。随着市场竞争的加剧和业务范围的拓展,企业内部的管理任务变得愈加繁重。传统的手工处理方式已无法满足......
  • java企业售后服务管理(ssm框架毕业设计)
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:在当今市场竞争日益激烈的环境下,企业除了注重产品的质量与创新外,越来越重视售后服务管理作为提升客户满意度和忠诚度的重要手段。随着消费者权益意识的增......
  • 访问JavaWeb项目报405错误
     一、问题由来一位朋友最近在学习JavaWeb开发,做测试时出现问题,页面报了405错误,HTTPStatus405?MethodNotAllowed如果是只出现一次,那也还好。主要是这个错误他遇到过多次,第一次就是刚开始学习Servlet的时候,还有一次是在学习文件上传的时候出现的。因此就特意写一篇博......
  • springboot/java/php/node/python农产品销售系统小程序【计算机毕设】
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义选题背景:随着互联网技术的迅猛发展,传统农产品销售模式正逐步向线上转移。小程序作为移动互联网的一种轻量级应用,因其开发成本低、传播快、使用方便等特点,成为连接......