2016-01-24 73 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。 –

相關問題