Java实现调用外部程序

news2024/12/27 13:36:36

Java实现调用外部程序

  • Java库
    • Runtime类与ProcessBuilder类
    • 参数传递
    • 执行结果
    • Runtime类的使用
    • ProcessBuilder类的使用
      • 无参数调用
      • 简单参数调用
      • 复杂参数调用
  • Apache Commons Exec库
    • 使用步骤介绍
    • 使用实例

Java库

在Java中,可以通过Runtime类ProcessBuilder类来实现调用外部程序。

Runtime类与ProcessBuilder类

使用Runtime类:

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec("外部程序路径");

使用ProcessBuilder类:

ProcessBuilder builder = new ProcessBuilder("外部程序路径");
Process process = builder.start();

参数传递

以上两种方法均可启动一个外部进程。如果需要向外部进程传递参数,可以在exec() 或ProcessBuilder构造函数中传递字符串数组

String[] cmdarray = {"外部程序路径", "参数1", "参数2"};
Process process = runtime.exec(cmdarray);

执行结果

外部进程的返回结果可以通过process对象获取。可以使用getInputStream() 方法读取外部进程的标准输出流,或者使用getErrorStream() 方法读取错误输出流。

InputStream inputStream = process.getInputStream(); // 标准输出流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String line;
while ((line = bufferedReader.readLine()) != null) {
    System.out.println(line); // 输出每行结果
}

注意:在调用外部程序时一定要小心,因为它可能会引起安全问题和系统崩溃等异常情况。建议使用该功能时对外部程序进行充分的测试和验证

Runtime类的使用

    @Test
    public void runtimeTest() {
        try {
            //获取执行进程
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec("ipconfig");

            //读取输入流
            InputStream inputStream = process.getInputStream();
            //将字节流转成字符流
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
            //字符缓冲区
            char[] c = new char[1024];
            int len = -1;
            while ((len = inputStreamReader.read(c)) != -1) {
                String s = new String(c, 0, len);
                System.out.print(s);
            }
            inputStream.close();
            inputStreamReader.close();
            //阻塞当前线程,直到进程退出为止
            process.waitFor();
            int exitValue = process.exitValue();
            if (exitValue == 0) {
                System.out.println("进程正常结束");
            } else {
                System.out.println("进程异常结束");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

在这里插入图片描述

ProcessBuilder类的使用

无参数调用

	@Test
    public void processBuilderTest1() {
        ProcessBuilder processBuilder = new ProcessBuilder();
        processBuilder.command("java");
        //将标准输入流和错误输入流合并,通过标准输入流读取信息
        processBuilder.redirectErrorStream(true);
        try {
            //启动进程
            Process start = processBuilder.start();
            //获取输入流
            InputStream inputStream = start.getInputStream();
            //转成字符输入流
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
            int len = -1;
            //字符缓冲区
            char[] c = new char[1024];
            //读取进程输入流中的内容
            while ((len = inputStreamReader.read(c)) !=-1){
                String s = new String(c, 0, len);
                System.out.print(s);
            }
            inputStreamReader.close();
            inputStream.close();
            //阻塞当前线程,直到进程退出为止
            start.waitFor();
            int exitValue = start.exitValue();
            if (exitValue == 0) {
                System.out.println("进程正常结束");
            } else {
                System.out.println("进程异常结束");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

在这里插入图片描述

简单参数调用

processBuilder.command("java","-version");

在这里插入图片描述

复杂参数调用

 List<String> command = new ArrayList<>();
        command.add("java");
        command.add("-version");
        processBuilder.command(command);

Apache Commons Exec库

Apache Commons Exec 是一个用于执行外部进程的 Java 库,可以方便地启动和控制进程,并且提供了对输入、输出流的管理和处理

使用步骤介绍

1.添加依赖,将Apache Commons Exec库添加到项目中

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

2.构造命令行对象:通过 CommandLine 对象构造需要执行的外部程序和参数。

CommandLine cmdLine = CommandLine.parse("command argument1 argument2");

3.创建执行器对象:通过 DefaultExecutor 对象创建一个执行器,并设置工作目录(可选)。

DefaultExecutor executor = new DefaultExecutor();
executor.setWorkingDirectory(new File("/your/workdir"));

4.创建处理器对象:PumpStreamHandler 对象可以处理输入输出流并存储进程的标准输出和标准错误信息。

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
executor.setStreamHandler(streamHandler);

5.执行命令并等待进程结束:调用 executor.execute方法执行命令。如果要等待进程执行完成对应的操作,请在此后调用 process.waitFor() 等待进程结束。执行完成后处理 outputStream 中的输出结果。

executor.execute(cmdLine);
String output = outputStream.toString("UTF-8");
System.out.println(output);

使用实例

    public static void main(String[] args) throws IOException {
        CommandLine cmdLine = CommandLine.parse("java -version");

        DefaultExecutor executor = new DefaultExecutor();

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
        executor.setStreamHandler(streamHandler);

        executor.execute(cmdLine);
        String output = outputStream.toString("UTF-8");
        System.out.println(output);
    }

执行输出结果:

java version "1.8.0_271"
Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/479376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

看看人家的MyBatis批量插入数据优化,从120s到2.5s,那叫一个优雅!

粗略的实验 最后 最近在压测一批接口的时候&#xff0c;我发现接口处理速度比我们预期的要慢。这让我感到有点奇怪&#xff0c;因为我们之前已经对这些接口进行了优化。但是&#xff0c;当我们进行排查时&#xff0c;发现问题出在数据库批量保存这块。 我们的项目使用了 myb…

开源小项目ChatGPT-website已获得100+star,我都干了什么

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…

微信小程序学习实录1(wxml文档、引入weui、双向数据绑定、提交表单到后端)

微信小程序学习实录 一、wxml文档二、新建页面快捷方式三、微信小程序引入weui四、双向数据绑定1.wxml渲染层2.js逻辑层 提交表单到后端五、微信小程序跳转到H5 一、wxml文档 <!-- index.wxml --> <view><!-- 数据绑定 --><view><text>{{name}}…

蛋白质界的 ChatGPT:AlphaFold2 论文必备知识,不会有人还不知道吧

你知道 AlphaFold2 吗&#xff1f;它真正解决了蛋白质三维结构预测的算法困境&#xff0c;堪称蛋白质界的 chat-GPT4&#xff0c;甚至它的意义不是 chat-GPT4 所能够匹敌的。它为世界疾病治疗药物开发以及探究生物生命之谜提供了通向天神的一条道路&#xff0c;未来是生物的世纪…

Java 基础入门篇(二)—— Java 基础语法

文章目录 一、注释二、字面量三、变量3.1 变量概述3.2 变量在计算机中的底层原理 四、数据类型五、关键字、标志符六、类型转换6.1 自动类型转换6.2 表达式的自动类型转换6.3 强制类型转换 七、运算符7.1 基本算数运算符7.2 符号做连接符7.3 自增自减运算符7.4 赋值运算符7.5 …

Java 基础入门篇(五)—— 面向对象编程

文章目录 一、面向对象的思想二、类的定义与对象的创建三、对象内存分配情况 ★ 3.1 两个对象的内存图3.2 两个变量指向同一个对象内存图 四、构造器4.1 构造器的格式与分类4.2 构造器的调用 五、 this 关键字六、封装七、标准JavaBean补充&#xff1a;局部变量和成员变量的区别…

Java 基础入门篇(六)—— String 类详解

文章目录 一、String 类概述二、String 创建对象的方式2.1 创建对象的两种方式2.2 面试&#xff1a;两种方式的区别 ★2.3 常见面试题 ★ 三、String 类常用方法3.1 字符串内容比较3.2 常用 API&#xff1a;遍历、截取、替换、分割 一、String 类概述 java.lang.String 类代表…

Java 基础入门篇(四)—— 方法的重载与参数传递机制

文章目录 一、方法的定义二、方法的参数传递机制 ★2.1 基本类型的参数传递2.2 引用类型的参数传递 三、方法重载 一、方法的定义 方法的作用&#xff1a;封装一段代码的语法结构&#xff0c;可以被重复调用&#xff0c;以此提高代码的复用性&#xff0c;提高开发效率&#xf…

【VsCode远程开发】Windows SSH远程连接Linux服务器 - 无公网IP内网穿透

文章目录 前言视频教程1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接远程服务器4. 公网远程连接4.1 ubuntu安装cpolar内网穿透4.2 创建隧道映射4.3 测试公网远程连接 5. 配置固定TCP端口地址5.1 保留一个固定TCP端口地址5.2 配置固定TCP端口地址5.3 测试固定公网地址远程 转…

Java 基础进阶篇(一)—— static 静态关键字与单例模式

文章目录 一、static 静态关键字1.1 静态成员变量与实例成员变量1.2 静态成员方法与实例成员方法1.3 static 访问注意事项1.4 内存使用情况 二、工具类三、代码块四、单例模式4.1 饿汉单例4.2 懒汉单例 一、static 静态关键字 static&#xff1a;代表静态的意思&#xff0c;可…

KaliLinux安装burpsuite(超详细)

注意事项 1.注意linux位数 安装jdk之前先输出uname -a&#xff0c;看看kali linux是32位的还是64位&#xff0c;例如此处我的kali是32位的&#xff0c;因此需下载的是32位的jdk 2.jdk版本 jdk版本最好是oracle的&#xff0c;若使用的是openjdk很可能会出现burpsuite闪退现象…

远程访问本地jupyter notebook服务 - 无公网IP端口映射

文章目录 前言视频教程1. Python环境安装2. Jupyter 安装3. 启动Jupyter Notebook4. 远程访问4.1 安装配置cpolar内网穿透4.2 创建隧道映射本地端口 5. 固定公网地址 转载自远控源码文章&#xff1a;公网远程访问jupyter notebook【cpolar内网穿透】 前言 Jupyter Notebook&am…

【Linux】信号的保存信号的捕捉信号集零碎知识点总结

【Linux】信号的保存&信号的捕捉&信号集&零碎知识点总结 一、信号的保存1.1 信号几种概念1.2 信号在内核中的表示 二、信号的捕捉了解用户态和内核态2.1 捕捉过程2.2 信号的捕捉方法2.3 信号捕捉规则2.4 多信号屏蔽问题 三、信号集3.1 概念3.2 信号集&#xff08;s…

【视频教程解读】Window上安装和使用autogluon V0.7

1.使用conda安装的python环境 教程使用的是极简版miniconda,由于我们的电脑中安装了anaconda&#xff0c;所以不需要进行进一步安装。python版本为3.9&#xff0c;博客里面有anaconda和python版本的对应关系。注意查看版本autogluon V0.4需要3.8或者3.9和3.10&#xff0c;pip版…

2023年第二十届五一数学建模B题:快递需求分析问题-思路详解

一、题目简析 今年的B题是一道较为综合的题目&#xff0c;包括了数据分析、综合评价、时间序列预测、最优化问题以及概率估计问题。考察范围广&#xff0c;但是整体看来题目背景简单&#xff0c;切入点多&#xff0c;难度适中。 二、逐问思路 1.问题1&#xff1a;附件1为该快…

私有GitLab仓库 - 本地搭建GitLab私有代码仓库并随时远程访问「内网穿透」

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar内网穿透5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 转载自远控源码文章&#xff1a;Linux搭建GitLab私有仓库&#xff0c;并内网穿透实现公…

迷你主机安装openwrt软路由系统(附启动盘制作教程+ISO、IMG镜像文件)

之前在迷你主机上刷了一个openwrt的软路由&#xff0c;安装过程分享给大家&#xff0c;镜像文件在文章末尾~ 一般需要做软路由系统的机器&#xff0c;是需要至少两个网口的&#xff0c;一个做wan口&#xff0c;一个做lan口 由于其他因素&#xff0c;不能直接将openwrt直接安装…

ChatGPT是什么?ChatGPT里的G、P、T分别指什么

文章目录 ChatGPT是什么GTP中的 生成式 是什么意思GTP中的 预训练 是什么意思GTP中的 变换模型 是什么意思 什么是Transformer什么是注意力机制 监督学Xi、无监督学Xi、强化学Xi ChatGPT是什么 GPT: Generative Pre-trained Transformer 生成式预训练变换模型 ChatGPT是由Ope…

学习RHCSA的day.02

目录 2.3常用简单命令 2.4使用Bash执行命令 2.5 命令帮助 2.3常用简单命令 常用系统工作命令 1、echo命令 echo命令用于在终端设备上输出字符串或变量提取后的值&#xff0c;语法格式为&#xff1a;“echo [字符串] [$变量]”。 这是在Linux系统中最常用的几个命令之一&am…

蒙蒂霍尔悖论

贝叶斯与频率主义对蒙蒂霍尔问题的解 在定义概率时&#xff0c;通常有两种思想流派&#xff1a;贝叶斯主义和频率主义。前者将概率视为我们对事件发生的信念程度&#xff0c;而后者则将其视为事件发生的相对频率。这篇文章介绍了使用贝叶斯和频率主义方法来解决著名的蒙蒂霍尔问…