我正在编写一个程序,执行以下工作:
- 使用 ProcessBuilder 运行命令(例如“svn info”或“svn diff”);
- 从进程的
getInputStream()
读取命令的输出; - 对于命令的输出,我想要:
- 解析输出并获取我想要的内容并稍后使用它,或者:
- 将输出直接写入指定文件。
现在我正在做的是使用 BufferedReader 逐行读取命令输出并将它们保存到 ArrayList 中,然后决定是否只扫描行查找某些内容或将这些行写入文件。
显然这是一个丑陋的工具,因为如果我希望将命令的输出保存到文件中,则不需要 ArrayList。那么您有什么建议,以更好的方式做到这一点?
这是我的一些代码:
使用它来运行命令并从进程的输出中读取
private ArrayList<String> runCommand(String[] command) throws IOException {
ArrayList<String> result = new ArrayList<>();
_processBuilder.command(command);
Process process = null;
try {
process = _processBuilder.start();
try (InputStream inputStream = process.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
String line;
while ((line = bufferedReader.readLine()) != null) {
result.add(line);
}
}
}
catch (IOException ex) {
_logger.log(Level.SEVERE, "Error!", ex);
}
finally {
if (process != null) {
try {
process.waitFor();
}
catch (InterruptedException ex) {
_logger.log(Level.SEVERE, null, ex);
}
}
}
return result;
}
在一种方法中我可以这样做:
ArrayList<String> reuslt = runCommand(command1);
for (String line: result) {
// ...parse the line here...
}
在另一个我可能会这样做:
ArrayList<String> result = runCommand(command2);
File file = new File(...filename, etc...);
try (PrintWriter printWriter = new PrintWriter(new FileWriter(file, false))) {
for (String line: result) {
printWriter.println(line);
}
}
最佳答案
在 ArrayList 中返回进程输出对我来说似乎是一个很好的抽象。然后 runCommand()
的调用者不需要担心命令是如何运行的或输出是如何读取的。除非您的命令非常冗长,否则额外列表使用的内存可能并不重要。
我唯一能看到这个问题的情况是调用者想要在命令仍在运行时开始处理输出,但这里似乎不是这种情况。
对于非常大的输出,您不想首先复制到内存中,一种选择是让 runCommand()
采取像 Guava 的 LineProcessor
这样的回调将调用输出的每一行。然后 runCommand() 仍然可以抽象出运行进程、读取输出以及随后关闭所有内容的整个过程,但是数据可以在回调运行时传递给回调,而不是等待方法在一个数组中返回整个响应。
关于java - 有没有更好的方法来读取进程的输入流,然后使用指定的方法进行处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8904720/