Przeczytaj cały tekst z pliku
Java 11 dodała metodę readString () do odczytu małych plików jako String
, zachowując terminatory linii:
String content = Files.readString(path, StandardCharsets.US_ASCII);
Dla wersji między Java 7 a 11, oto kompaktowy, solidny idiom zawarty w metodzie narzędziowej:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
Czytaj wiersze tekstu z pliku
Java 7 dodała wygodną metodę odczytu pliku jako wiersza tekstu reprezentowanego jako List<String>
. To podejście jest „stratne”, ponieważ separatory linii są usuwane z końca każdej linii.
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
Java 8 dodała Files.lines()
metodę tworzenia Stream<String>
. Ponownie, ta metoda jest stratna, ponieważ separatory linii są usuwane. Jeśli IOException
podczas odczytu pliku zostanie napotkany, jest on zawijany w UncheckedIOException
, ponieważ Stream
nie akceptuje lambd, które zgłaszają sprawdzone wyjątki.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
To Stream
wymaga close()
połączenia; jest to słabo udokumentowane w interfejsie API i podejrzewam, że wiele osób nawet nie zauważa, że Stream
maclose()
metodę. Pamiętaj, aby użyć bloku ARM, jak pokazano.
Jeśli pracujesz ze źródłem innym niż plik, możesz zamiast tego użyć lines()
metodyBufferedReader
Wykorzystanie pamięci
Pierwsza metoda, która zachowuje podział wiersza, może tymczasowo wymagać pamięci kilkakrotnie większej niż rozmiar pliku, ponieważ przez krótki czas surowa zawartość pliku (tablica bajtów) i zdekodowane znaki (z których każdy ma 16 bitów, nawet jeśli jest zakodowany 8 plików w pliku) znajdują się jednocześnie w pamięci. Najbezpieczniej jest zastosować do plików, o których wiadomo, że są małe w stosunku do dostępnej pamięci.
Druga metoda, czytanie linii, jest zwykle bardziej wydajna pod względem pamięci, ponieważ bufor bajtów wejściowych do dekodowania nie musi zawierać całego pliku. Jednak nadal nie nadaje się do plików, które są bardzo duże w stosunku do dostępnej pamięci.
Do odczytu dużych plików potrzebujesz innego projektu dla swojego programu, który odczytuje fragment tekstu ze strumienia, przetwarza go, a następnie przechodzi do następnego, ponownie wykorzystując ten sam blok pamięci o stałej wielkości. Tutaj „duży” zależy od specyfikacji komputera. Obecnie ten próg może wynosić wiele gigabajtów pamięci RAM. Trzecia metoda, przy użyciu a, Stream<String>
jest jednym ze sposobów, aby to zrobić, jeśli twoje wejściowe „rekordy” są przypadkami pojedynczych linii. (Zastosowanie readLine()
metody BufferedReader
jest proceduralnym odpowiednikiem tego podejścia).
Kodowanie znaków
Jednej rzeczy, której brakuje w próbce w oryginalnym poście, jest kodowanie znaków. Istnieją pewne szczególne przypadki, w których domyślna platforma jest tym, czego chcesz, ale są one rzadkie i powinieneś być w stanie uzasadnić swój wybór.
StandardCharsets
Klasa zdefiniowanie pewnych stałych dla kodowania wymagane od wszystkich środowisk wykonawczych Java:
String content = readFile("test.txt", StandardCharsets.UTF_8);
Domyślna platforma jest dostępna wCharset
samej klasie :
String content = readFile("test.txt", Charset.defaultCharset());
Uwaga: ta odpowiedź w dużej mierze zastępuje moją wersję Java 6. Narzędzie Java 7 bezpiecznie upraszcza kod, a stara odpowiedź, która używała odwzorowanego bufora bajtów, uniemożliwiała usunięcie odczytanego pliku, dopóki zmapowany bufor nie został wyrzucony. Możesz wyświetlić starą wersję za pomocą linku „edytowanego” w tej odpowiedzi.