• java Process 执行批命令 cmd


    1、初始化 Process

    1. Process process = new ProcessBuilder(command).redirectErrorStream(true).start();
    2. 或者
    3. Process process = Runtime.getRuntime().exec(cmd);

     redirectErrorStream(true)

    错误输出与标准输出合并,以便通过使用Process类的getInputStream()方法可以读取错误并输出

    通过子进程所产生的任何错误输出随后由该对象的start()方法启动将与标准输出合并, 这样既可以用Process.getInputStream()方法来读取。此使得更容易与对应的输出相关的错误消息。初始值是false。

    2、处理流

    1. int exitcode = process .waitFor();
    2. new PrintStream(process .getErrorStream(), "error").start();
    3. new PrintStream(process .getInputStream(), "input").start();
    process创建的子进程没有自己的控制台或终端,其所有的io操作都是通过(输入流、输出流、错误流)重定向到父进程中,如果该可执行程序的输入、输出或者错误输出比较多的话,而由于运行窗口的标准输入、输出等缓冲区有大小的限制,则可能导致子进程阻塞,甚至产生死锁,其解决方法就是在waitfor()方法之前读出窗口的标准输出、输出、错误缓冲区中的内容
    
    所以,建议process .waitFor(); 放在处理流后面等待
    1. new PrintStream(process .getErrorStream(), "error").start();
    2. new PrintStream(process .getInputStream(), "input").start();
    3. int exitcode = process .waitFor();

    3、处理多输入交换参数

    (1)使用expect4j

    1. Process process = Runtime.getRuntime().exec("...");
    2. Expect expect = new ExpectBuilder()
    3. .withInputs(process.getInputStream())
    4. .withOutput(process.getOutputStream())
    5. .withErrorOnTimeout(true)
    6. .build();
    7. expect.expect(contains("Password:"));
    8. expect.sendLine("secret");
    9. expect.close();

    (2)使用Threa.sleep

    本来输出流,以为使用(win)\r\n或(linux)\n 模拟回车就可以输入参数。但是不起作用。

    Thread.sleep(1000);在输入之间等待一段时间.将脚本在下一个输入之前消耗上个输入

    1. OutputStream outputStream = process.getOutputStream();
    2. outputStream.write(new String("1var").getBytes());
    3. Thread.sleep(1000); //https://www.it1352.com/2342759.html
    4. outputStream.write(new String("1tyh").getBytes());
    5. outputStream.flush();
    6. outputStream.close(); //写入完成后必须得执行 flush() 和 close() 方法,否则进程无法判断写入是否完成,导致写入失败;

    (3)使用1024字节数组

    一个 SET/P 语句的输入限制为 1024 个字符.我们可以使用它来解决这种情况,通过管道传输一个比 1024 小一个字符的缓冲区.因此,下一个输入的第一个字符将使缓冲区满,这将导致消耗输入并继续执行下一个语句.所以如果你使用这种转换方法,您的代码将按预期工作.事实上,你甚至可以省去刷新缓存

    1. OutputStream outputStream = process.getOutputStream();
    2. outputStream.write(convert("tester"));
    3. outputStream.write(convert("25"));
    4. outputStream.flush();
    5. outputStream.close(); //写入完成后必须得执行 flush() 和 close() 方法,否则进程无法判断写入是否完成,导致写入失败;
    6. public static byte[] convert(String str){
    7. byte[] asBytes = str.getBytes();
    8. byte[] result = new byte[1023];
    9. for(int i = 0; i < asBytes.length; i++)
    10. result[i] = asBytes[i];
    11. return result;
    12. }
    13. }

    代码

    1. /**
    2. * 用于处理Runtime.getRuntime().exec产生的错误流及输出流
    3. */
    4. public class PrintStreamextends Thread {
    5. InputStream is;
    6. String type;
    7. OutputStream os;
    8. PrintStream(InputStream is, String type) {
    9. this(is, type, null);
    10. }
    11. PrintStream(InputStream is, String type, OutputStream redirect) {
    12. this.is = is;
    13. this.type = type;
    14. this.os = redirect;
    15. }
    16. public void run() {
    17. InputStreamReader isr = null;
    18. BufferedReader br = null;
    19. PrintWriter pw = null;
    20. try {
    21. if (os != null)
    22. pw = new PrintWriter(os);
    23. isr = new InputStreamReader(is);
    24. br = new BufferedReader(isr);
    25. String line=null;
    26. while ( (line = br.readLine()) != null) {
    27. if (pw != null)
    28. pw.println(line);
    29. System.out.println(type + ">" + line);
    30. }
    31. if (pw != null)
    32. pw.flush();
    33. } catch (IOException ioe) {
    34. ioe.printStackTrace();
    35. } finally{
    36. try {
    37. pw.close();
    38. br.close();
    39. isr.close();
    40. } catch (IOException e) {
    41. e.printStackTrace();
    42. }
    43. }
    44. }
    45. }

    参考:

    如何使用 Java Process Builder 执行接受多个输入的批处理脚本? - IT屋-程序员软件开发技术分享社区

    java - 如何将参数传递给Java Process? - Thinbug 

    Java Process详解及实例_罗汉翔的博客-CSDN博客 

    java执行bat命令碰到阻塞 java执行bat命令碰到的阻塞问题的解决办法(IT技术)

  • 相关阅读:
    训练正常&异常的GAN损失函数loss变化应该是怎么样的
    net-java-php-python-汽车租赁系统计算机毕业设计程序
    MetaGPT day06 Environment组件源码 多智能体辩论
    Linux中系统时间同步
    单例模式(初学)
    Java 操作FTP服务器进行下载文件
    30个CSS选择器
    java毕业设计——基于java+JSP+J2EE的城市公交查询系统设计与实现——城市公交查询系统
    计算机系大学生为什么选择在CSDN写博客?
    堡垒机有录像吗?好用吗?有什么作用?
  • 原文地址:https://blog.csdn.net/qq_30436011/article/details/127979994