2015-07-01 11 views
11

Muss der folgende Code in try-with-resources eingebunden werden, um sicherzustellen, dass die zugrunde liegende Datei geschlossen ist?Sammelt die Operation "Stream" den Stream und die zugrunde liegenden Ressourcen?

List<String> rows = Files.lines(inputFilePath).collect(Collectors.toList()); 
+2

Das Design von Stream und close() war sehr umstritten . Um sicherzugehen, schließen Sie immer einen Stream, wenn Sie sich nicht sicher sind. Und auch das ist vielleicht nicht genug, siehe http://stackoverflow.com/questions/20319417/why-is-bufferedreader-not-closed-when-obaining-streamstring-in-try-with-res – ZhongYu

Antwort

8

Als Javadoc- des überlasteten Files#lines(Path, Charset) Verfahrenszustände

Der zurückStrom kapselt eine Reader. Wenn eine rechtzeitige Entsorgung der Systemressourcen erforderlich ist, sollte das try-with-resources-Konstrukt verwendet werden, um sicherzustellen, dass die close-Methode des Streams aufgerufen wird, nachdem die Stream-Operationen abgeschlossen sind.

Also ja, wickeln die Stream von lines in einer try-with-resources Anweisung zurückgegeben. (. Oder close es angemessen)

15

Es gibt einen Trick, um die Stream Implementierung close() nach dem Terminalbetrieb Aufruf:

List<String> rows = Stream.of(Files.lines(inputFilePath)).flatMap(s->s) 
        .collect(Collectors.toList()); 

Es schafft einfach einen Strom den Strom von Linien als ein einzelnes Element einkapseln und Verwendungen flatMap mit einer Identitätsfunktion (Function.identity() würde auch funktionieren), um es in einen Strom von Linien wieder zu verwandeln.

Der interessante Punkt ist ein property of Stream.flatMap(…):

Jeder gemappt Strom geschlossen wird, nachdem dessen Inhalt in diesen Strom in Verkehr gebracht wurden.

Der obige Code schließt also den Zeilenstrom. Während es prägnanter aussieht, hat es den Nachteil gegenüber Versuchen mit Ressourcen, dass die aktuelle Implementierung von flatMaplacks lazy evaluation hier nicht relevant ist, da Sie ohnehin alle Zeilen in eine Liste sammeln. Aber es ist etwas zu beachten, wenn Sie diesen Trick in anderen Szenarien verwenden.


Für den Code der Frage, wie sie ist gibt es eine noch einfachere Lösung:

List<String> rows = Files.readAllLines(inputFilePath); 

Liest alle Zeilen und schließt alle Ressourcen ...

Verwandte Themen