0

我正在编写一个执行以下工作的程序:

  1. 使用 ProcessBuilder 运行命令(如“svn info”或“svn diff”);
  2. 从进程的getInputStream();读取命令的输出
  3. 使用命令的输出,我想要:
    • 解析输出并得到我想要的并在以后使用它,或者:
    • 将输出直接写入指定文件。

现在我正在做的是使用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);
    }
}
4

2 回答 2

1

在 ArrayList 中返回进程输出对我来说似乎是一个很好的抽象。那么调用者runCommand()就不需要担心命令是如何运行的或输出是如何读取的。除非您的命令非常冗长,否则额外列表使用的内存可能并不重要。

我唯一能看到这是一个问题的情况是调用者想要在命令仍在运行时开始处理输出,这似乎不是这里的情况。

对于您不想首先复制到内存中的非常大的输出,一种选择是runCommand()采用像 Guava 这样的回调LineProcessor,它将为输出的每一行调用。然后runCommand()仍然可以抽象出运行进程、读取输出和之后关闭所有内容的整个过程,但是可以在回调运行时将数据传递给回调,而不是等待方法在一个数组中返回整个响应。

于 2012-01-18T03:29:26.920 回答
0

我认为在某些情况下无用地存储文本不是性能问题。尽管如此,为了清洁,最好写两种方法:

private ArrayList<String> runCommand(String[] command)

private void runCommandAndDumpToFile(String[] command, File file)

(从您的问题中不太清楚,但我假设您在运行进程之前知道您是将输出写入文件还是处理它。)

于 2012-01-18T03:47:04.247 回答