Прочитать весь текст из файла
В Java 11 добавлен тег readString () для чтения небольших файлов как String
, сохраняя символы конца строки:
String content = Files.readString(path, StandardCharsets.US_ASCII);
Для версий между Java 7 и 11 вот компактная и надежная идиома, заключенная в служебный метод:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
Прочитать строки текста из файла
В Java 7 добавлен удобный метод чтения файла в виде строк текста, представленный как List<String>
. Этот подход подразумевает потери, поскольку разделители строк удаляются с конца каждой строки.
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
В Java 8 добавлен тег _ 6_ для создания Stream<String>
. Опять же, этот метод с потерями, потому что разделители строк удаляются. Если при чтении файла встречается IOException
, он помещается в UncheckedIOException
, поскольку Stream
не принимает лямбда-выражения, которые генерируют проверенные исключения.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
Для этого Stream
требуется close()
< / a> вызов; это плохо задокументировано в API, и я подозреваю, что многие люди даже не замечают, что Stream
имеет close()
метод. Обязательно используйте блок ARM, как показано на рисунке.
Если вы работаете с источником, отличным от файла, вы можете использовать _ 16_ в BufferedReader
.
Использование памяти
Первый метод, который сохраняет разрывы строк, может временно потребовать память, в несколько раз превышающую размер файла, потому что на короткое время необработанное содержимое файла (массив байтов) и декодированные символы (каждый из которых имеет 16 бит, даже если он закодирован как 8 бит в файле) одновременно находятся в памяти. Безопаснее всего применять к файлам, которые, как вы знаете, имеют небольшой размер по сравнению с доступной памятью.
Второй метод, чтение строк, обычно более эффективен с точки зрения памяти, поскольку входной байтовый буфер для декодирования не должен содержать весь файл. Однако он по-прежнему не подходит для файлов, которые очень велики по сравнению с доступной памятью.
Для чтения больших файлов вам понадобится другой дизайн вашей программы, такой, который считывает фрагмент текста из потока, обрабатывает его, а затем переходит к следующему, повторно используя тот же блок памяти фиксированного размера. Здесь многое зависит от характеристик компьютера. В настоящее время этот порог может составлять несколько гигабайт оперативной памяти. Третий метод с использованием Stream<String>
- это один из способов сделать это, если ваши входные записи являются отдельными строками. (Использование readLine()
метода BufferedReader
является процедурным эквивалентом этого подхода.)
Кодировка символов
Одна вещь, которой не хватает в образце исходного сообщения, - это кодировка символов. Есть некоторые особые случаи, когда платформа по умолчанию - это то, что вы хотите, но они редки, и вы должны быть в состоянии обосновать свой выбор.
Класс StandardCharsets
определяет некоторые константы для кодировки, необходимые для всех сред выполнения Java:
String content = readFile("test.txt", StandardCharsets.UTF_8);
Платформа по умолчанию доступна по адресу сам Charset
класс:
String content = readFile("test.txt", Charset.defaultCharset());
Примечание. Этот ответ в значительной степени заменяет мою версию Java 6. Утилита Java 7 безопасно упрощает код, а старый ответ, в котором использовался сопоставленный байтовый буфер, предотвращал удаление файла, который был прочитан, до тех пор, пока сопоставленный буфер не будет собран сборщиком мусора. Вы можете просмотреть старую версию по отредактированной ссылке в этом ответе.
person
erickson
schedule
28.11.2008
byte[] Files.readAllBytes(file);
Тем, кто предлагает решение «однострочного» сканера: не нужно ли его закрывать? - person Val   schedule 17.01.2012