Читать весь текст из файла
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 добавил Files.lines()
метод для создания Stream<String>
. Опять же, этот метод с потерями, потому что разделители строк удалены. Если IOException
при чтении файла встречается an, он оборачивается в UncheckedIOException
, так Stream
как не принимает лямбда-выражения, которые выдают проверенные исключения.
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
Это Stream
действительно нужно close()
позвонить; это плохо документировано в API, и я подозреваю, что многие люди даже не замечают, что у Stream
него есть close()
метод. Обязательно используйте ARM-блок, как показано на рисунке.
Если вы работаете с источником, отличным от файла, вы можете использовать lines()
метод BufferedReader
вместо.
Использование памяти
Первый метод, который сохраняет разрывы строк, может временно требовать памяти в несколько раз больше размера файла, потому что в течение короткого времени сырое содержимое файла (байтовый массив) и декодированные символы (каждый из которых составляет 16 бит, даже если они закодированы) как 8 бит в файле) находятся в памяти одновременно. Безопаснее всего применять файлы, которые, как вы знаете, имеют небольшой размер относительно доступной памяти.
Второй метод, чтение строк, обычно более эффективен для использования памяти, поскольку входной буфер байтов для декодирования не должен содержать весь файл. Тем не менее, он все еще не подходит для файлов, которые очень велики по отношению к доступной памяти.
Для чтения больших файлов вам понадобится другой дизайн вашей программы, который читает фрагмент текста из потока, обрабатывает его, а затем переходит к следующему, повторно используя тот же блок памяти фиксированного размера. Здесь «большой» зависит от технических характеристик компьютера. В настоящее время этот порог может составлять много гигабайт оперативной памяти. Третий метод, использующий a, 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 безопасно упрощает код, а старый ответ, в котором используется сопоставленный байтовый буфер, предотвращает удаление прочитанного файла до тех пор, пока сопоставленный буфер не будет очищен от мусора. Вы можете просмотреть старую версию по "отредактированной" ссылке на этот ответ.