我有一个日志文件,我想用它来创建一个LogMessage
对象。我想从文件中流式传输线条,并将每个线条映射到新的LogMessage
。下面的代码有效,但Eclipse发出警告:
资源泄漏:' lineStream'从未关闭
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
块,并在那里关闭它,那么当方法返回时我会关闭流(我认为)。在任何情况下,它在我使用它时都会关闭。
那么确保内部流关闭的最佳方法是什么?或者代码可能是正确的,但Eclipse并没有意识到它?
答案 0 :(得分:3)
你实际上不应该需要这些,而是:
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
}