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

Map one stream to another stream and close the first when the second closes

我有一个日志文件,我想用它的每一行来创建一个 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 块,并在那里关闭它,那么当方法 returns 时流将关闭(我认为)。反正我来用的时候已经关了

那么确保内部流关闭的最佳方法是什么?或者也许代码是正确的,但 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) returns 一个 Stream<Path> 已经有一个关闭处理程序关闭内部 BufferedReader。当此 Stream 映射到 Stream<LogMessage> 时,关闭处理程序将保留。

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

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

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