java - 将一个流映射到另一个流并在第二个关闭时关闭第一个

标签 java eclipse resources java-8 java-stream

我有一个日志文件,其中的每一行我都想用来创建一个 LogMessage 对象。我想流式传输文件中的行,并将每一行映射到新的 LogMessage。下面的代码有效,但 Eclipse 发出警告:

Resource leak: 'lineStream' is never closed

public static Stream<LogMessage> streamSingleLineLogMessages(Path path) {
    try {
        Stream<String> lineStream = Files.lines(path, StandardCharsets.ISO_8859_1);
        Stream<LogMessage> logMessageStream =
                lineStream.map(message -> new LogMessage(path, message));
        logMessageStream.onClose(lineStream::close);
        return logMessageStream;
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

如果我添加一个 finally block ,并在那里关闭它,那么当方法返回时流将关闭(我认为)。无论如何,到我要使用它的时候它已经关闭了。

那么确保内部流关闭的最佳方式是什么?或者也许代码是正确的,但 Eclipse 没有意识到这一点?

最佳答案

你实际上不应该需要这些,而是​​:

public static Stream<LogMessage> streamSingleLineLogMessages(Path path) throws IOException {
    return Files.lines(path, StandardCharsets.ISO_8859_1)
                .map(message -> new LogMessage(path, message));
}

方法 Files.lines(path, cs) 返回 Stream<Path>已经有一个关闭处理程序关闭内部 BufferedReader .当此 Stream 映射到 Stream<LogMessage> 时, 关闭处理程序被保留。

这意味着对于新的 Stream<LogMessage> , 已经有一个关闭处理程序关闭 BufferedReader , 所以你不需要自己添加它。

您只需要确保在使用此方法时,将其属性包装在 try-with-resources 中构造:

try (Stream<LogMessage> messageStream = streamSingleLineLogMessages(path)) {
    // do something with the stream
}

关于java - 将一个流映射到另一个流并在第二个关闭时关闭第一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34977627/

相关文章:

android - 在 Android 中保存长文本的最佳实践

java - 在 Eclipse 比较编辑器中不显示隐藏符号作为两个文件的区别

eclipse - 如何从 Eclipse 的编辑器选项卡中删除关闭按钮?

java - 如何重新绘制 JLabel?

Mac OSX 中的 Eclipse 键盘快捷键

java - 如何在 if 语句中使用 try-with-resources?

java - 如何在 Clojure 中加载程序资源

java - 在java中生成表

java - 使用 Java 创建可打印的每日计划/文档

java - 接收两个自然数并计算其中一个在另一个中出现的次数。 java