gpt4 book ai didi

java - 如何使用 Java ProcessBuilder 自动执行命令行脚本

转载 作者:行者123 更新时间:2023-11-30 02:00:35 28 4
gpt4 key购买 nike

我是java的新手,我正在尝试使用java自动化命令行。我试图在这里寻找解决方案,但找不到。

我创建了一个简单的测试 shell 脚本,如下所示来测试我的程序:

<小时/>
#!/bin/bash
echo "What is your name?";
read name;
echo "Hello, $name"
echo "What is your contact number?";
read num;
echo "Saved contact number $num for $name"
<小时/>

Java代码如下:

import java.io.*;
import java.util.*;

public class CmdLineMain {
public static void main(String args[]) throws InterruptedException, IOException {
List<String> command = new ArrayList<String>();
command.add("./test.sh");

ProcessBuilder builder = new ProcessBuilder(command);

final Process process = builder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = "";
BufferedWriter bw = null;

while (process.isAlive()) {
line = br.readLine();
// since stream may be closed earlier, re-open it
bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
System.out.println(line);

if (line != null) {
switch (line) {
case "What is your name?":
bw.write("John Doe");
bw.close();
break;
case "What is your contact number?":
bw.write("123456789");
bw.close();
break;

}
}

}

System.out.println("Program terminated!");
}
}
<小时/>

问题:进程的第二个输入失败并出现错误:

<小时/>
    What is your name?
Hello, John Doe
What is your contact number?
Exception in thread "main" java.io.IOException: Stream Closed
at java.io.FileOutputStream.writeBytes(Native Method)
at java.io.FileOutputStream.write(FileOutputStream.java:326)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at java.io.FilterOutputStream.close(FilterOutputStream.java:158)
at sun.nio.cs.StreamEncoder.implClose(StreamEncoder.java:320)
at sun.nio.cs.StreamEncoder.close(StreamEncoder.java:149)
at java.io.OutputStreamWriter.close(OutputStreamWriter.java:233)
at java.io.BufferedWriter.close(BufferedWriter.java:266)
at nkh.app.CmdLineMain.main(CmdLineMain.java:34)
<小时/>

最佳答案

关闭BufferedWriter将关闭其底层流,这包括通过process.getOutputStream()获取的进程OutputStream。因此,一旦它在一个循环中关闭,在下一个循环中,您的 BufferedWriter 就会包装一个关闭的流。相反,仅将输出流包装一次并重复使用。

像这样:

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
// while the stream is open and there is something to read
// probably a better condition than `process.isAlive()`
while ((line = br.readLine()) != null) {
switch (line) {
case "What is your name?":
bw.write("John Doe");
bw.newLine();
bw.flush();
break;
case "What is your contact number?":
bw.write("123456789");
bw.newLine();
bw.flush();
break;
}
}
<小时/>

当您的新 BufferedWriter 被调用时,您的原始代码在 close() 而不是在其之前的 write() 上终止的原因包装封闭的底层流是因为 BufferedOutputStream.write() 可能尚未实际写入底层流,因为它已被缓冲。调用 flush() 应该告诉流实际写入,正如您在堆栈跟踪中看到的那样,close() 正在调用 flush() ,其中最终将缓冲的字节写入底层的FileOutputStream,然后意识到FileOutputStream已经关闭。

关于java - 如何使用 Java ProcessBuilder 自动执行命令行脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52988779/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com