我有一个日志文件,其中的每一行我都想用来创建一个 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/