当前位置:   article > 正文

Runtime、ProcessBuilder的区别(Java中,两种方法来启动其他程序)

processbuilder

目录

■Runtime、ProcessBuilder 区别:

■Java中提供了两种方法来启动其他程序

■代码

・Runtime

・ProcessBuilder

■类的方法

・Process.waitFor()方法

・Process.getErrorStream()方法

・Process.redirectErrorStream(true)方法:

■可运行代码

・java代码   (直接运行)

・运行的bat代码

・结果

・java代码   (运行,并获取运行的程序 的 输出)

・对应的bat代码 (有输出)

・运行结果(可以获得输出)

■Java Process.exitValue & Process.waitFor()

■其它资料整理

■参考


=================

■Runtime、ProcessBuilder 区别:

ProcessBuilder.start() 和 Runtime.exec()传递的参数有所不同,
・Runtime.exec()可接受一个单独的字符串,这个字符串是通过空格来分隔可执行命令程序和参数的;
・ProcessBuilder的构造函数是一个字符串列表或者数组。列表中第一个参数是可执行命令程序,其他的是命令行执行是需要的参数。

Java中提供了两种方法来启动其他程序

也就是说,
在编写Java程序时,有时候我们需要调用其他的诸如 exe,bat ,shell  这样的程序或脚本。在Java中提供了两种方法来启动其他程序:
(1) 使用Runtime的exec()方法
(2) 使用ProcessBuilder的start()方法

■代码

・Runtime

  1. String command = "/XXXX/XXX/xxx.bat param1";
  2. Process pro1 = Runtime.getRuntime().exec(command);
  3. InputStream errorInfo = pro1.getErrorStream();

====

・ProcessBuilder

  1. List<String> commandList = new ArrayList<>();
  2. commandList.add("/XXXX/XXX/xxx.bat");
  3. commandList.add("param1");
  4. ProcessBuilder pb = new ProcessBuilder(commandList);
  5. Process pro2 = pb.start();
  6. pro2.waitFor();

===

■类的方法

・Process.waitFor()方法

processBuilder.start() 会立刻返回,不会待ps进程结束。所以Process提供waitFor方法,调用后线程阻塞,直到ps命令结束。
 

・Process.getErrorStream()方法

创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin,stdout,stderr)操作都将通过三个流 (getOutputStream(),getInputStream(),getErrorStream()) 重定向到父进程。
 

・Process.redirectErrorStream(true)方法:

合并输出流和错误流。

Process阻塞问题_Dancen的博客-CSDN博客_process start 阻塞

  1. public int execute()
  2. {
  3. int rs = 0;
  4. String[] cmds = {...};//command and arg
  5. ProcessBuilder builder = new ProcessBuilder(cmds);
  6. builder.redirectErrorStream(true);
  7. Process process = builder.start();
  8. BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
  9. String output = null;
  10. while (null != (readLine = br.readLine()))
  11. {
  12. print(output);
  13. }
  14. rs = process.waitFor();
  15. return rs;
  16. }

==

■可运行代码

・java代码   (直接运行)

  1. package com.sxz.study.process;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public class TestProcess {
  6. public static void main(String[] args) {
  7. List<String> commandList = new ArrayList<>();
  8. commandList.add("C:\\myBat\\CreateFile.bat");
  9. commandList.add("test0001");
  10. commandList.add("the test 0002 row");
  11. commandList.add("theTest0003Row");
  12. ProcessBuilder pb = new ProcessBuilder(commandList);
  13. Process pro2 = null;
  14. try {
  15. pro2 = pb.start();
  16. // =====CreateFile.bat=================================START
  17. // @echo off
  18. //
  19. // set param1=%1
  20. // set param2=%2
  21. // set param3=%3
  22. //
  23. // cd %~dp0
  24. //
  25. // echo %param1%>testProcess.txt
  26. // echo %param2%>>testProcess.txt
  27. // echo %param3%>>testProcess.txt
  28. // =====CreateFile.bat=================================END
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. }
  32. try {
  33. pro2.waitFor();
  34. } catch (InterruptedException e) {
  35. e.printStackTrace();
  36. }
  37. }
  38. }

・运行的bat代码

  1. @echo off
  2. set param1=%1
  3. set param2=%2
  4. set param3=%3
  5. cd %~dp0
  6. echo %param1%>testProcess.txt
  7. echo %param2%>>testProcess.txt
  8. echo %param3%>>testProcess.txt

・结果

 ====

  1. test0001
  2. "the test 0002 row"
  3. theTest0003Row

・java代码   (运行,并获取运行的程序 的 输出)

获取输出核心代码

  1. List<String> commandList = new ArrayList<>();
  2. commandList.add("C:\\myBat\\CreateFile.bat");
  3. 。。。
  4. ProcessBuilder pb = new ProcessBuilder(commandList);
  5. Process pro2 = null;
  6. 。。。。
  7. try {
  8. pro2 = pb.start();
  9. InputStreamReader ir = new InputStreamReader(pro2.getInputStream());
  10. LineNumberReader ls = new LineNumberReader(ir);
  11. String line = "";
  12. while ((line = ls.readLine()) != null) {
  13. System.out.println("---" + line);
  14. }
  15. 。。。

===全部代码===

  1. package com.sxz.study.process;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.io.LineNumberReader;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. public class TestProcess {
  8. public static void main(String[] args) {
  9. List<String> commandList = new ArrayList<>();
  10. commandList.add("C:\\myBat\\CreateFile.bat");
  11. commandList.add("test0001");
  12. commandList.add("the test 0002 row");
  13. commandList.add("theTest0003Row");
  14. ProcessBuilder pb = new ProcessBuilder(commandList);
  15. Process pro2 = null;
  16. try {
  17. pro2 = pb.start();
  18. // =====CreateFile.bat=================================START
  19. // @echo off
  20. // chcp 65001
  21. //
  22. // set param1=%1
  23. // set param2=%2
  24. // set param3=%3
  25. //
  26. // echo "Begin..."
  27. //
  28. // cd %~dp0
  29. //
  30. // echo %param1%>testProcess.txt
  31. // echo %param2%>>testProcess.txt
  32. // echo %param3%>>testProcess.txt
  33. //
  34. // dir
  35. //
  36. // echo "End..."
  37. // =====CreateFile.bat=================================END
  38. InputStreamReader ir = new InputStreamReader(pro2.getInputStream());
  39. LineNumberReader ls = new LineNumberReader(ir);
  40. String line = "";
  41. while ((line = ls.readLine()) != null) {
  42. System.out.println("---" + line);
  43. }
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. }
  47. try {
  48. pro2.waitFor();
  49. } catch (InterruptedException e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. }

・对应的bat代码 (有输出)

  1. @echo off
  2. chcp 65001
  3. set param1=%1
  4. set param2=%2
  5. set param3=%3
  6. echo "Begin..."
  7. cd %~dp0
  8. echo %param1%>testProcess.txt
  9. echo %param2%>>testProcess.txt
  10. echo %param3%>>testProcess.txt
  11. dir
  12. echo "End..."

・运行结果(可以获得输出)

 === 

 ===

■Java Process.exitValue & Process.waitFor()

都可以获得返回值,推荐使用  Process.waitFor()

Process.exitValue() 采用非阻塞的方式返回,如果没有立即拿到返回值,则抛出异常

Process.waitFor() 当前线程等待,如有必要,一直要等到由该 Process 对象表示的进程已经终止。但是如果我们在调用此方法时,如果不注意的话,很容易出现主线程阻塞,Process也挂起的情况。在调用waitFor() 的时候,Process需要向主线程汇报运行状况,所以要注意清空缓存区,即InputStream和ErrorStream,在网上,很多只提到处理 InputStream,忽略了ErrorStream。以下一段代码,贴出来,仅做参考。

======

以下面的代码为例

  1. package com.sxz.study.process;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.io.LineNumberReader;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. public class TestProcess {
  8. public static void main(String[] args) {
  9. List<String> commandList = new ArrayList<>();
  10. commandList.add("C:\\myBat\\CreateFile.bat");
  11. commandList.add("test0001");
  12. commandList.add("the test 0002 row");
  13. commandList.add("theTest0003Row");
  14. ProcessBuilder pb = new ProcessBuilder(commandList);
  15. Process pro2 = null;
  16. try {
  17. pro2 = pb.start();
  18. // =====CreateFile.bat=================================START
  19. // chcp 65001
  20. // @echo off
  21. //
  22. // set param1=%1
  23. // set param2=%2
  24. // set param3=%3
  25. //
  26. // cd %~dp0
  27. // echo "Test out put"
  28. //
  29. // echo %param1%>testProcess.txt
  30. // echo %param2%>>testProcess.txt
  31. // echo %param3%>>testProcess.txt
  32. //
  33. // ping localhost
  34. // =====CreateFile.bat=================================END
  35. InputStreamReader ir = new InputStreamReader(pro2.getInputStream());
  36. LineNumberReader ls = new LineNumberReader(ir);
  37. String line ="";
  38. while((line = ls.readLine())!=null){
  39. System.out.println("----:"+line);
  40. }
  41. int result1 = pro2.exitValue();
  42. System.out.println("result1----"+result1);
  43. } catch (IOException e) {
  44. e.printStackTrace();
  45. }
  46. try {
  47. int result2 = pro2.waitFor();
  48. System.out.println("result2----"+result2);
  49. } catch (InterruptedException e) {
  50. e.printStackTrace();
  51. }
  52. }
  53. }

正常运行的结果

----:
----: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的区

====

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/428328
推荐阅读
相关标签
  

闽ICP备14008679号