2016-01-24 93 views
1

我有一个日志文件,我想用它们的每一行创建一个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没有意识到它?

+1

原来的资源泄漏分析尚未更新为Java 8的方法引用。我提交了https://bugs.eclipse.org/486506 –

回答

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)返回已经有着密切的处理程序关闭内部BufferedReader一个Stream<Path>的方法。将此流映射到Stream<LogMessage>时,会保留关闭处理程序。

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

你只需要确保当您使用此方法,你把它包装一个try-with-resources构造内财产:

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

我使用'streamSingleLineLogMessages'作为lambda函数。所以它不能抛出检查的异常。 –

+1

@whistling_marmot如果'Files.lines'引发异常,'streamSingleLineLogMessages'将抛出'IOException'。 – Tunaki

+0

但是,内联'lineStream'(就像在你的代码中一样)会使eclipse警告消失,即使我保持try-catch。 –

相关问题