有没有更好的方法来读取进程的输入流,然后使用指定的方法进行处理?

发布于 2024-12-28 01:56:59 字数 1923 浏览 1 评论 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);
    }
}

I am writing a program doing the following works:

  1. Run a command using ProcessBuilder (like "svn info" or "svn diff");
  2. Read the output of the command from the process's getInputStream();
  3. With the output of the command, I want either:
    • Parse the output and get what I want and use it later, OR:
    • Write the output directly to a specified file.

Now what I am doing is using BufferedReader to read whatever the command outputs by lines and save them to an ArrayList, and then decide if I would just scan the lines to find out something or write the lines to a file.

Obviously this is an ugly implement because the ArrayList should not be needed if I want a command's output to be saved to a file. So what will you suggest, to do it in a better way?

Here is some of my codes:

Use this to run command and read from the output of the process

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;
}

and in one method I may do like this:

ArrayList<String> reuslt = runCommand(command1);

for (String line: result) {
    // ...parse the line here...
}

and in another I may do like this:

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);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我的奇迹 2025-01-04 01:56:59

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

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

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

Returning the process output in an ArrayList seems like a fine abstraction to me. Then the caller of runCommand() doesn't need to worry about how the command was run or the output read. The memory used by the extra list is probably not significant unless your command is very prolix.

The only time I could see this being an issue would be if the caller wanted to start processing the output while the command was still running, which doesn't seem to be the case here.

For very big output that you don't want to copy into memory first, one option would be to have runCommand() take a callback like Guava's LineProcessor that it will call for each line of the output. Then runCommand() can still abstract away the whole deal of running the process, reading the output, and closing everything afterwards, but data can be passed out to the callback as it runs rather than waiting for the method to return the whole response in one array.

嘿嘿嘿 2025-01-04 01:56:59

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

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

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

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

I don't think it's a performance issue that you store the text uselessly in some cases. Nonetheless, for cleanliness, it might be better to write two methods:

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

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

(It wasn't quite clear from your question, but I assume that you know before running your process whether you'll just write the output to file or process it.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文