赞
踩
目录
・Process.redirectErrorStream(true)方法:
■Java Process.exitValue & Process.waitFor()
=================
ProcessBuilder.start() 和 Runtime.exec()传递的参数有所不同,
・Runtime.exec()可接受一个单独的字符串,这个字符串是通过空格来分隔可执行命令程序和参数的;
・ProcessBuilder的构造函数是一个字符串列表或者数组。列表中第一个参数是可执行命令程序,其他的是命令行执行是需要的参数。
也就是说,
在编写Java程序时,有时候我们需要调用其他的诸如 exe,bat ,shell 这样的程序或脚本。在Java中提供了两种方法来启动其他程序:
(1) 使用Runtime的exec()方法
(2) 使用ProcessBuilder的start()方法
- String command = "/XXXX/XXX/xxx.bat param1";
- Process pro1 = Runtime.getRuntime().exec(command);
- InputStream errorInfo = pro1.getErrorStream();
====
- List<String> commandList = new ArrayList<>();
- commandList.add("/XXXX/XXX/xxx.bat");
- commandList.add("param1");
- ProcessBuilder pb = new ProcessBuilder(commandList);
- Process pro2 = pb.start();
- pro2.waitFor();
===
processBuilder.start() 会立刻返回,不会待ps进程结束。所以Process提供waitFor方法,调用后线程阻塞,直到ps命令结束。
创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin,stdout,stderr)操作都将通过三个流 (getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程。
合并输出流和错误流。
Process阻塞问题_Dancen的博客-CSDN博客_process start 阻塞
- public int execute()
- {
- int rs = 0;
- String[] cmds = {...};//command and arg
- ProcessBuilder builder = new ProcessBuilder(cmds);
- builder.redirectErrorStream(true);
- Process process = builder.start();
- BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
- String output = null;
- while (null != (readLine = br.readLine()))
- {
- print(output);
- }
- rs = process.waitFor();
- return rs;
- }
==
- package com.sxz.study.process;
-
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.List;
-
- public class TestProcess {
-
- public static void main(String[] args) {
-
- List<String> commandList = new ArrayList<>();
- commandList.add("C:\\myBat\\CreateFile.bat");
- commandList.add("test0001");
- commandList.add("the test 0002 row");
- commandList.add("theTest0003Row");
- ProcessBuilder pb = new ProcessBuilder(commandList);
- Process pro2 = null;
- try {
- pro2 = pb.start();
- // =====CreateFile.bat=================================START
- // @echo off
- //
- // set param1=%1
- // set param2=%2
- // set param3=%3
- //
- // cd %~dp0
- //
- // echo %param1%>testProcess.txt
- // echo %param2%>>testProcess.txt
- // echo %param3%>>testProcess.txt
- // =====CreateFile.bat=================================END
-
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- try {
- pro2.waitFor();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
-
- }
-
- }
- @echo off
-
- set param1=%1
- set param2=%2
- set param3=%3
-
- cd %~dp0
-
- echo %param1%>testProcess.txt
- echo %param2%>>testProcess.txt
- echo %param3%>>testProcess.txt
====
- test0001
- "the test 0002 row"
- theTest0003Row
获取输出核心代码
- List<String> commandList = new ArrayList<>();
- commandList.add("C:\\myBat\\CreateFile.bat");
- 。。。
- ProcessBuilder pb = new ProcessBuilder(commandList);
- Process pro2 = null;
- 。。。。
- try {
- pro2 = pb.start();
-
- InputStreamReader ir = new InputStreamReader(pro2.getInputStream());
- LineNumberReader ls = new LineNumberReader(ir);
- String line = "";
- while ((line = ls.readLine()) != null) {
- System.out.println("---" + line);
- }
- 。。。
===全部代码===
- package com.sxz.study.process;
-
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.LineNumberReader;
- import java.util.ArrayList;
- import java.util.List;
-
- public class TestProcess {
-
- public static void main(String[] args) {
-
- List<String> commandList = new ArrayList<>();
- commandList.add("C:\\myBat\\CreateFile.bat");
- commandList.add("test0001");
- commandList.add("the test 0002 row");
- commandList.add("theTest0003Row");
- ProcessBuilder pb = new ProcessBuilder(commandList);
- Process pro2 = null;
- try {
- pro2 = pb.start();
- // =====CreateFile.bat=================================START
- // @echo off
- // chcp 65001
- //
- // set param1=%1
- // set param2=%2
- // set param3=%3
- //
- // echo "Begin..."
- //
- // cd %~dp0
- //
- // echo %param1%>testProcess.txt
- // echo %param2%>>testProcess.txt
- // echo %param3%>>testProcess.txt
- //
- // dir
- //
- // echo "End..."
- // =====CreateFile.bat=================================END
-
- InputStreamReader ir = new InputStreamReader(pro2.getInputStream());
- LineNumberReader ls = new LineNumberReader(ir);
- String line = "";
- while ((line = ls.readLine()) != null) {
- System.out.println("---" + line);
- }
-
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- try {
- pro2.waitFor();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
-
- }
-
- }
- @echo off
- chcp 65001
-
- set param1=%1
- set param2=%2
- set param3=%3
-
- echo "Begin..."
-
- cd %~dp0
-
- echo %param1%>testProcess.txt
- echo %param2%>>testProcess.txt
- echo %param3%>>testProcess.txt
- dir
-
- echo "End..."
===
===
都可以获得返回值,推荐使用 Process.waitFor()
Process.exitValue() 采用非阻塞的方式返回,如果没有立即拿到返回值,则抛出异常
Process.waitFor() 当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。但是如果我们在调用此方法时,如果不注意的话,很容易出现主线程阻塞,Process也挂起的情况。在调用waitFor() 的时候,Process需要向主线程汇报运行状况,所以要注意清空缓存区,即InputStream和ErrorStream,在网上,很多只提到处理 InputStream,忽略了ErrorStream。以下一段代码,贴出来,仅做参考。
======
以下面的代码为例
- package com.sxz.study.process;
-
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.LineNumberReader;
- import java.util.ArrayList;
- import java.util.List;
-
- public class TestProcess {
-
- public static void main(String[] args) {
-
- List<String> commandList = new ArrayList<>();
- commandList.add("C:\\myBat\\CreateFile.bat");
- commandList.add("test0001");
- commandList.add("the test 0002 row");
- commandList.add("theTest0003Row");
- ProcessBuilder pb = new ProcessBuilder(commandList);
- Process pro2 = null;
- try {
- pro2 = pb.start();
- // =====CreateFile.bat=================================START
- // chcp 65001
- // @echo off
- //
- // set param1=%1
- // set param2=%2
- // set param3=%3
- //
- // cd %~dp0
- // echo "Test out put"
- //
- // echo %param1%>testProcess.txt
- // echo %param2%>>testProcess.txt
- // echo %param3%>>testProcess.txt
- //
- // ping localhost
- // =====CreateFile.bat=================================END
-
- InputStreamReader ir = new InputStreamReader(pro2.getInputStream());
- LineNumberReader ls = new LineNumberReader(ir);
- String line ="";
- while((line = ls.readLine())!=null){
- System.out.println("----:"+line);
- }
-
- int result1 = pro2.exitValue();
- System.out.println("result1----"+result1);
-
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- try {
- int result2 = pro2.waitFor();
- System.out.println("result2----"+result2);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
-
-
- }
-
- }
正常运行的结果
----:
----:C:\myProject\20230321\MyJava001\MyJava001>chcp 65001
----:Active code page: 65001
----:"Test out put"
----:
----:Pinging DLC5CG1464WW9L.dir.svc.accenture.com [::1] with 32 bytes of data:
----:Reply from ::1: time<1ms
----:Reply from ::1: time<1ms
----:Reply from ::1: time<1ms
----:Reply from ::1: time<1ms
----:
----:Ping statistics for ::1:
----: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
----:Approximate round trip times in milli-seconds:
----: Minimum = 0ms, Maximum = 0ms, Average = 0ms
result1----0
result2----0
如果去掉40-45行,则会报错
Exception in thread "main" java.lang.IllegalThreadStateException: process has not exited
at java.lang.ProcessImpl.exitValue(ProcessImpl.java:510)
at com.sxz.study.process.TestProcess.main(TestProcess.java:47)
https://blog.csdn.net/sxzlc/article/details/128607097
ProcessBuilder 、Runtime和Process 的区别_sunshine_pb的博客-CSDN博客_processbuilder和runtime的区
====
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。