ProcessBuilder类的介绍及使用_Process和ProcessBuilder入门

ProcessBuilder类的介绍及使用

前言

在做一个项目的时候需要用到运行时动态执行JAVA命令,一开始的思路是运行时生成bat脚本,然后通过Runtime类的exec方法之行bat脚本,但是此方法不好的地方在于脚本执行时会弹出一个cmd程序界面框。后面在参考YANG的源码时发现了另一种运行时执行JAVA命令的方法,由此延申,了解了PorcessBuilder类的作用及用法。

正文

ProcessBuilder类是java.lang包下的基础类,在使用时无需导入,可以直接使用。它主要用于创建和运行各类外部程序,例如javac,java等等。

–构造方法–

它(List command),它(String… command)

–常用方法–

void command(String... command) 用于将待执行命令及参数传递给它;Process start() 执行命令并返回一个Process对象,用于获取对执行程序的输入和输出;void directory(File base) 用于设置待执行命令的工作目录,可以不设置;

–使用技巧–

1、在使用它的时候建议将其封装一下,这样更便于使用,例如,

public class ProcessUtil {public static void process(String... command) throws Exception {process((File)null, command);}public static void process(List<String> commandList) throws Exception {process((File)null, (String[])commandList.toArray(new String[0]));}public static void process(File base, String... command) throws Exception {ProcessBuilder processBuilder = new ProcessBuilder(new String[0]);if (base != null) {
​      processBuilder.directory(base);}
​    processBuilder.command(command);Process process = processBuilder.start();......1. 添加一个input2string()方法,用于将执行程序获得的输出转换为String对象,便于输出,例如,public static String input2str(InputStream inputStream) throws UnsupportedEncodingException {ByteArrayOutputStream outSteam = new ByteArrayOutputStream();byte[] buffer = new byte[1024];try {int len;while((len = inputStream.read(buffer)) != -1) {
​        outSteam.write(buffer, 0, len);}
​      outSteam.close();
​      inputStream.close();} catch (IOException var5) {
​      var5.printStackTrace();}return outSteam.toString("utf-8");}

总结

它作为一个JAVA底层类,使开发者能够与操作系统进行强大的互动,而且在使用它进行系统命令的调用时,能够在后台进行,不会有使用Runtime类时弹出cmd命令执行框的困扰,十分方便。在后面的学习当中可以进一步了解一下System类的用法。



ProcessBuilder

1. 简介

ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。在J2SE 1.5之前,都是由Process类处来实现进程的控制管理。
每个 ProcessBuilder 实例管理一个进程属性集。它的start() 方法利用这些属性创建一个新的 Process 实例。start() 方法可以从同一实例重复调用,以利用相同的或相关的属性创建新的子进程。

2. 示例

下面是一个使用修改过工作目录和环境启动进程的例子,并重定向标准输出和标准错误到自定义日志文件。

ProcessBuilder pb =new ProcessBuilder("myCommand", "myArg1", "myArg2");//设置环境变量,初始值是当前进程环境的一个副本System.getenv()Map<String, String> env = pb.environment();  env.put("VAR1", "myValue");env.remove("OTHERVAR");env.put("VAR2", env.get("VAR1") + "suffix");//设置工作目录pb.directory(new File("myDir"));   File log = new File("log");//redirectErrorStream 属性默认值为false,意思是子进程的标准输出和错误输出被发送给两个独立的流,这些流可以通过 Process.getInputStream() 和 Process.getErrorStream() 方法来访问。 //如果将值设置为 true,标准错误将与标准输出合并。这使得关联错误消息和相应的输出变得更容易。在此情况下,合并的数据可从 Process.getInputStream() 返回的流读取,而从 Process.getErrorStream() 返回的流读取将直接到达文件尾。pb.redirectErrorStream(true);pb.redirectOutput(Redirect.appendTo(log));//启动进程Process p = pb.start();assert pb.redirectInput() == Redirect.PIPE;//重定向标准输出到日志assert pb.redirectOutput().file() == log;assert p.getInputStream().read() == -1;

3. ProcessBuilder API

//构造方法 //利用指定的操作系统程序和参数构造一个进程生成器。 
ProcessBuilder(List<String> command) 
//利用指定的操作系统程序和参数构造一个进程生成器。
ProcessBuilder(String… command) //方法 //返回此进程生成器的操作系统程序和参数。 
command() 
//设置此进程生成器的操作系统程序和参数。 
command(List<String> command) 
//设置此进程生成器的操作系统程序和参数。 
command(String… command) //返回此进程生成器的工作目录。 
directory() 
//设置此进程生成器的工作目录。
directory(File directory) 
//返回此进程生成器环境的字符串映射视图。 environment方法获得运行进程的环境变量,得到一个Map,可以修改环境变量 
environment() 
//返回进程生成器是否合并标准错误和标准输出;true为合并,false为不合并
redirectErrorStream() 
//设置此进程生成器的 redirectErrorStream 属性。默认值为false不合并
redirectErrorStream(boolean redirectErrorStream) 
//使用此进程生成器的属性启动一个新进程。
start() 

Process和ProcessBuilder入门

java在本地执行命令时是否遇到过问题? 执行长输出的命令会卡住的情况,用Runtime.exe() 执行命令,当命令的输出过长时,会导致程序卡住,当时查的网上资料解决了这个问题,开启了2个线程,分别打印标准输出和标准错误输出,这样就能避免卡住。 Process 创建的是进程,因为在本地 ps 会看到一个执行的进程。

ProcessBuilder

1.概述

ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。在J2SE 1.5之前,都是由Process类处来实现进程的控制管理。

每个 ProcessBuilder 实例管理一个进程属性集。它的start() 方法利用这些属性创建一个新的 Process 实例。

使用ProcessBuilder比使用Process的好处在于,我们不仅仅可以去执行一个应用程序,还可以对执行进程进行更多的管理工作,比如:获取进程的执行信息,包括标准输出、标准错误输出;设置当前工作目录;改变环境参数。

ProcessBuilder用于创建操作系统进程,每个ProcessBuilder实例都管理一个进程属性集合。通过调用start()方法,可以通过这些属性创建出一个进程。start()方法可以被多次调用,来创建多个独立的进程。

每个builder管理着下面的进程属性:

cmmand

命令,比如{“ipcofig”,“/all”}

environment

环境变量,子进程会直接使用当前进程的环境变量。环境变量是独立的,因此可以被修改,但是不会影响其他的进程。

directory

工作目录,如果返回的是Null,说明当前目录使用的是系统变量user.dir所在的目录。

redirectErrorStream属性

默认是false。Flase意味着标准输出和标准错误是两个独立的流,可以通过Process.getInputStream()和Process.getErrorStream()方法获得。

如果这个值设置为true,那么标准错误将会合并到标准输出中,并且发往同一个目标地址(这种特性使得错误消息可以很方便的和输出消息一起管理),此时,如果你再想要单独获取错误输出流,就会得到null。

线程安全

注意这个类不是线程安全的,因此如果多个线程使用ProcessBuilder实例,并且修改属性,那么可能会造成冲突。因此需要在外面进行线程同步。

启动

可以简单的向下面这样启动一个进程:

 Process p = new ProcessBuilder("myCommand", "myArg").start();

样例

下面是官方文档中给出的样例,样例中修改了工作目录以及环境变量,并且把标准错误和标准输出合并输出到日志文件中:

 ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");Map<String, String> env = pb.environment();env.put("VAR1", "myValue");env.remove("OTHERVAR");env.put("VAR2", env.get("VAR1") + "suffix");pb.directory(new File("myDir"));File log = new File("log");pb.redirectErrorStream(true);pb.redirectOutput(Redirect.appendTo(log));Process p = pb.start();assert pb.redirectInput() == Redirect.PIPE;assert pb.redirectOutput().file() == log;assert p.getInputStream().read() == -1;

ProcessBuilder(XXX).start()和Runtime.exec(XXX)功能相同,主要优点在使用过程中感受有:

  • 前者是jdk1.5后的新方式
  • 配置环境变量时更优雅
  • 对当前目录的控制也更合理
  • 错误流重定向特别方便
  • 进程控制更简洁

参考:

https://blog.csdn.net/qq_21383435/article/details/82709284

https://blog.csdn.net/u013256816/article/details/54603910

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

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

相关文章

c语言不能在函数中求数组大小,C语言中数组长度不能用变量定义吗?

翻翻过去那场雪1、C语言中不支持。C中支持变长数组(你可以自行度娘变长数组和alloca函数)&#xff0c;但是因为其实在栈上分配&#xff0c;不被推荐使用。做为解决方案&#xff0c;你可以使用C式的malloc函数或者C式的new函数来在堆上动态分配内存&#xff0c;这样长度是完全可…

Java如何基于ProcessBuilder类调用外部程序

Java如何基于ProcessBuilder类调用外部程序 demo1 Testpublic void testProcessBuilder() {ProcessBuilder processBuilder new ProcessBuilder(); // processBuilder.command("ping","127.0.0.1");processBuilder.command("ipconfig");//…

计算机专业课程设计报告c语言,计算机程序设计(C语言)课程设计报告.doc

计算机程序设计(C语言)课程设计报告.doc计算机程序设计C语言课程设计报告题目电子动画时钟 学院 机电工程学院专业 班级090109班学号 姓名 指导教师 设计日期 一、概述选题背景 随着社会的进步和科技的发展&#xff0c;电子钟表逐渐成为了人们生活中不可缺少的一部分。设计思路…

Java ProcessBuilder类学习

文章目录一、ProcessBuilder基础1、ProcessBuilder类1.1 概述1.2 进程属性2、Process类2.1 概述2.2 Process抽象类2.3 创建Process对象方式3、ProcessBuilder与Runtime.exec()异同3.1 相同点3.2 不同点二、**ProcessBuilder**实战1、API介绍2、实战demo一、ProcessBuilder基础 …

c语言用栈编写数制转换程序,数制转换-栈的应用(C++实现)

本程序实现的是十进制与不同进制之间的的数据转换&#xff0c;利用的数据结构是栈&#xff0c;基本数学方法辗转相除法。conversion.h#includeusing namespace std;//将十进制的数据n转换成m进制的数据stack conversion(unsigned int n,unsigned int m){stack s;while(n){s.pus…

Java replace和replaceAll的区别以及用法

replace和replaceAll是JAVA中常用的替换字符的方法 public String replace(char oldChar, char newChar) 在字符串中用newChar字符替代oldChar字符&#xff0c;返回一个新的字符串 public String replaceAll(String regex,String replacement)使用给定的 replacement 字符串替…

两个变量实现查找坏环c语言,C/C++编程笔记:C语言编程知识要点总结!大一C语言知识点(全)...

程序员无言 2020-07-07一、C语言程序的构成与C、Java相比&#xff0c;C语言其实很简单&#xff0c;但却非常重要。因为它是C、Java的基础。不把C语言基础打扎实&#xff0c;很难成为程序员高手。1、C语言的结构先通过一个简单的例子&#xff0c;把C语言的基础打牢。C语言的结构…

Java-使用Math,实现lg、平方、开方、round、floor、ceil

一、lg 使用方法:Math.log10() public class MathMethod {public static void main(String[] args) {int a100;double b100;float c100;System.out.println("lg的实现&#xff1a;"Math.log10(a));System.out.println("lg的实现&#xff1a;"Math.log10(…

累加器A用c语言,累加器A的主要作用是什么_一文解析累加器a和acc的区别

描述累加器简介在中央处理器中&#xff0c;累加器(accumulator) 是一种寄存器&#xff0c;用来储存计算产生的中间结果。如果没有像累加器这样的寄存器&#xff0c;那么在每次计算 (加法&#xff0c;乘法&#xff0c;移位等等) 后就必须要把结果写回到内存&#xff0c;也许马上…

Java中的Math函数常用方法总结

Math函数中常用的一些方法 类Math包含用于执行基本数字运算的方法 算术运算 Math.abs(a)&#xff1a;取a的绝对值Math.sqrt(a)&#xff1a;取a的平方根Math.cbrt(a)&#xff1a;取a的立方根Math.max(a,b)&#xff1a;取a、b之间的最大值Math.min(a,b)&#xff1a;取a、b之间…

单片机C语言节日彩灯,单片机c语言节日彩灯控制器设计.docx

单片机c语言节日彩灯控制器设计湖南涉外经济学院课程设计报告课程名称&#xff1a;单片机原理及应用报告题目&#xff1a;节日彩灯控制器的设计学生姓名&#xff1a;所在学院&#xff1a;信息科学与工程学院专业班级&#xff1a;电子信息工程1102班学生学号&#xff1a;指导教师…

Java中的<<、>>、>>>运算符

二进制中的原码、反码、补码 有符号数&#xff1a; 对于有符号数而言&#xff0c;符号的正、负机器是无法识别的&#xff0c;但由于“正、负”恰好是两种截然不同的状态&#xff0c;如果用“0”表示“正”&#xff0c;用“1”表示“负”&#xff0c;这样符号也被数字化了&…

c语言随机漫步,基于最短路径的随机游走算法研究与应用

摘要&#xff1a;近年来,人们越来越多地关注数据集中数据点之间的关系。不同种类的网络相继涌现。有链接和节点类型都单一的同质网络如以朋友友谊为基础建立起来的社交网站;以网络链接形成的互联网。另外还有多种链接和节点类型形成的异质网络如医学领域病人,疾病与治疗方法或者…

JAVA中的NAN

JAVA中的NAN NaN表示非数值&#xff0c;例如&#xff1a;0.0/0结果为NAN&#xff0c;负数的平方根结果也为NAN。 所有非数值的值都认为是不相同的&#xff0c;所有我们在检测NAN时使用 ""是检测不到的 if(x Double.Nan) //这样是检测不到的需要使用Double.isNaN…

actionscript 3.0 怎么写android 程序,(ActionScript3.0笔记)第一个程序HelloWorld!

(ActionScript3.0笔记)第一个程序HelloWorld!创建我的第一个ActionScript3.0程序--HelloWord&#xff01;首先下载ActionScript3.0的集成开发环境&#xff0c;FLASH CS4 Professional。从网站下载FLASH CS4 Professional软件的安装包程序&#xff0c;下载好后进行安装。安装后在…

android判断是否json格式,android – 检查JSON中是否存在subObject

您可以尝试一下,如果尝试失败,则返回null.或者你可以将你的尝试分解成小块来监视失败的地方./*** This method will return the JSONObject q0, if it exists* If it doesnt exist it will return NULL**/private JSONObject getQZero(JSONObject json){try{return json.getJSO…

Java中double类型精度丢失的问题_double类型数据加减操作精度丢失解决方法_BigDecimal取整

BigDecimal在用double做入参的时候&#xff0c;二进制无法精确地表示十进制小数&#xff0c;编译器读到字符串"0.0000002"和“1.0000002”之后&#xff0c;必须把它转成8个字节的double值&#xff0c;也就是1.0000001999999998947288304407265968620777130126953125类…

Spring 官方修复零日漏洞,推出 Spring Boot 2.6.6、2.5.12 等新版本

一、漏洞说明 这个漏洞还要从 3 月 29 日晚间说起&#xff01; 彼时有不少网友爆料&#xff0c;Spring 框架出现 “史诗级” RCE 漏洞&#xff0c;平地一声雷&#xff0c;一时之间&#xff0c;快要入睡的开发者们纷纷坐起查看关于漏洞的情况&#xff0c;闹得技术圈中人心惶惶…

android.app.activityview,ViewModel 概览

ViewModel 概览ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。注意&#xff1a;如需将 ViewModel导入 Android 项目&#xff0c;请参阅 Lifecycle 版本说明中关于声明依赖项的说明。Android 框架可…

MySQL事务与MVVC

一、ACID特性 数据库管理系统中**事务(transaction)**的四个特性(分析时根据首字母缩写依次解释)&#xff1a;原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability) 所谓事务&#xff0c;它是一个操作序列&#xff0c;这些操作要么都执行&#xff0…