Leggi tutto il testo da un file
Java 11 ha aggiunto il metodo readString () per leggere piccoli file come a String
, preservando i terminatori di riga:
String content = Files.readString(path, StandardCharsets.US_ASCII);
Per le versioni tra Java 7 e 11, ecco un linguaggio compatto, robusto, racchiuso in un metodo di utilità:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
Leggi righe di testo da un file
Java 7 ha aggiunto un metodo pratico per leggere un file come righe di testo, rappresentato come a List<String>
. Questo approccio è "lossy" perché i separatori di riga vengono eliminati dalla fine di ogni riga.
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 ha aggiunto il Files.lines()
metodo per produrre a Stream<String>
. Ancora una volta, questo metodo è in perdita perché i separatori di riga vengono eliminati. Se IOException
durante la lettura del file viene rilevato un , viene racchiuso in un UncheckedIOException
, poiché Stream
non accetta lambdas che generano eccezioni verificate.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
Questo Stream
ha bisogno di una close()
chiamata; questo è scarsamente documentato sull'API e sospetto che molte persone non si accorgano nemmeno che Stream
ha un close()
metodo. Assicurarsi di utilizzare un blocco ARM come mostrato.
Se si sta lavorando con una fonte diversa da un file, è possibile utilizzare il lines()
metodo BufferedReader
, invece.
Utilizzo della memoria
Il primo metodo, che preserva le interruzioni di riga, può richiedere temporaneamente memoria più volte la dimensione del file, perché per un breve periodo il contenuto del file non elaborato (un array di byte) e i caratteri decodificati (ognuno dei quali è 16 bit anche se codificato come 8 bit nel file) risiedono in memoria contemporaneamente. È più sicuro applicare a file che si ritiene siano piccoli rispetto alla memoria disponibile.
Il secondo metodo, leggere le righe, di solito è più efficiente in termini di memoria, poiché il buffer di byte di input per la decodifica non deve contenere l'intero file. Tuttavia, non è ancora adatto a file di dimensioni molto grandi rispetto alla memoria disponibile.
Per leggere file di grandi dimensioni, è necessario un design diverso per il programma, uno che legge una porzione di testo da un flusso, lo elabora e passa al successivo, riutilizzando lo stesso blocco di memoria di dimensioni fisse. Qui, "grande" dipende dalle specifiche del computer. Al giorno d'oggi, questa soglia potrebbe essere di molti gigabyte di RAM. Il terzo metodo, usando a Stream<String>
è un modo per farlo, se i tuoi "record" di input sono linee individuali. (L'uso del readLine()
metodo di BufferedReader
è l'equivalente procedurale di questo approccio.)
Codifica dei caratteri
Una cosa che manca nell'esempio nel post originale è la codifica dei caratteri. Ci sono alcuni casi speciali in cui l'impostazione predefinita della piattaforma è ciò che desideri, ma sono rari e dovresti essere in grado di giustificare la tua scelta.
La StandardCharsets
classe definisce alcune costanti per le codifiche richieste per tutti i runtime Java:
String content = readFile("test.txt", StandardCharsets.UTF_8);
L'impostazione predefinita piattaforma è disponibile presso la Charset
classe di sé:
String content = readFile("test.txt", Charset.defaultCharset());
Nota: questa risposta sostituisce ampiamente la mia versione di Java 6. L'utilità di Java 7 semplifica in modo sicuro il codice e la vecchia risposta, che utilizzava un buffer di byte mappato, impediva l'eliminazione del file letto fino a quando il buffer mappato non veniva raccolto. È possibile visualizzare la versione precedente tramite il collegamento "modificato" su questa risposta.