2015-07-01 17 views
11

Il seguente codice deve essere inserito in try-with-resources per assicurarsi che il file sottostante sia chiuso?L'operazione di raccolta su Stream chiude il flusso e le risorse sottostanti?

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

Il design di Stream e close() è stato molto controverso . Per sicurezza, chiudi sempre uno Stream se non sei sicuro. E anche questo potrebbe non essere sufficiente, vedi http://stackoverflow.com/questions/20319417/why-is-bufferedreader-not-closed-when-obtaining-streamstring-in-try-with-res – ZhongYu

risposta

8

Come il javadoc del Files#lines(Path, Charset) metodo di overload afferma

Il flusso restituito incapsula un Reader. Se è necessario lo smaltimento tempestivo delle risorse di sistema del file , è necessario utilizzare il costrutto try-with-resources per per garantire che il metodo di chiusura del flusso venga richiamato dopo il completamento delle operazioni dello stream .

Quindi sì, avvolgere il Stream restituito dal lines in un comunicato try-with-resources. (. O close in modo appropriato)

15

c'è un trucco per rendere la Stream implementazione chiamando close() dopo l'operazione del terminale:

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

Esso crea semplicemente un flusso di incapsulare il flusso di linee come un unico elemento e usi flatMap con una funzione di identità (Function.identity() funzionerebbe pure) per trasformarlo nuovamente in un flusso di linee.

Il punto interessante è un property of Stream.flatMap(…):

Ogni flusso mappato viene chiusa dopo il suo contenuto sono stati inseriti in questo flusso.

Quindi il codice sopra chiuderà il flusso di linee. Anche se sembra più conciso, ha lo svantaggio di provare con le risorse l'attuale implementazione di flatMaplacks lazy evaluation che non è rilevante in questo caso poiché si stanno raccogliendo tutte le linee in un elenco. Ma è qualcosa da tenere a mente quando si utilizza questo trucco in altri scenari.


Per il codice della domanda come-è che non c'è una soluzione ancora più semplice:

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

Legge tutte le linee e chiude tutte le risorse ...