Java прочитать файл в строку

Обновлено: 07.07.2024

В Java есть четыре основных абстрактных класса, реализующих потоки ввода-вывода: InputStream, OutputStream, Reader, Writer. Первые два работают с байтами, вторые – с символами.

Для работы с файлами от этих абстрактных классов созданы соответственно классы FileInputStream, FileOutputStream, FileReader, FileWriter. Они являются адаптерами для объектов класса File к "интерфейсам" InputStream, OutputStream, Reader, Writer, т. е. к их методам.

Скажем несколько слов об адаптере как паттерне, или шаблоне, проектирования. Класс-адаптер A наследуется от интерфейса B, к которому приспосабливается объект другого класса – C. Класс-адаптер A имеет поле типа класса объекта C.

Например, объект File адаптируется к потоку ввода InputStream, т. е. все, что мы хотим получить из File, в конечном итоге мы будем получать из InputStream. Фактически мы работаем с InputStream, через адаптер FileInputStream, который с одной стороны наследуется от InputStream, а с другой – имеет поле, которому присваивается объект File.

Адаптер выполняет работу по получению данных из файла и адаптации их к тому виду, который можно передать в методы InputStream. Класс-адаптер, в данном примере – FileInputStream, переопределяет методы InputStream, добавляя в них свой код.

В основной ветке сначала создается объект, для которого требуется адаптер. Затем создается переменная класса, к которому выполняется адаптация. Этой переменной присваивается объект класса-адаптера, в конструктор которого передается адаптируемый объект.

Часто переменную определяют самим классом-адаптером:

В конструктор можно передать строку-адрес. Объект File будет создан внутри адаптера. Пример побайтового копирования файла:

Если используются относительные адреса, они должны начинаться от корня проекта.

В конструктор FileOutputStream можно также передать второй аргумент true. В этом случае, если файл существует, данные в него будут добавляться. Перезаписи файла не произойдет.

Метод available() объекта класса FileInputStream возвращает количество непрочитанных байтов. Метод read() читает один байт и расширяет его до типа int. Кроме этого, есть другой метод read(), читающий массив байт в переменную-аргумент и возвращающий количество реально прочитанных байт. Метод write() также позволяет записывать блоками.

При чтении конца файла блок может содержать меньше прочитанных байт, чем размерность массива. Поэтому write() позволяет указывать срез массива.

У объектов FileOutputStream имеется метод flush(), который принудительно записывает находящиеся в буфере байты на диск. При вызове close() это происходит автоматически.

С помощью класса PrintStream также можно создать поток вывода в файл. PrintStream является наследником FilterOutputStream, который в свою очередь наследник OutputStream как и FileOutputStream.

Функция printf() предназначена для форматированного вывода.

Заметим, переменная System.out является объектом типа PrintStream.

В работе с вводом-выводом также используется другой паттерн проектирования – обертка (wrapper), он же декоратор (decorator). Декоратор расширяет функциональность объекта, а не приспосабливает объект к какому-либо стороннему интерфейсу.

Поэтому класс-обертка наследуется от того же класса или интерфейса, что и оборачиваемый объект. В классе-обертке переопределяются методы оборачиваемого объекта. В методах обертки вызываются методы оборачиваемого класса и вводится дополнительная функциональность.

В основной ветке создается объект оборачиваемого класса, который передается в конструктор обертки. Внутри класса-обертки есть поле типа декорируемого класса. Этому полю присваивается переданный объект.

BufferedInputStream – класс-обертка для InputStream (наследует через FilterInputStream). В отличие от InputStream класс BufferedInputStream позволяет предварительно читать в буфер порции байт, что уменьшает количество обращений к файлу. Существует также BufferedOutputStream.

Конструктор класса BufferedInputStream принимает объект InputStream или его наследника.

Хотя данные считываются блоками, метод read() извлекает их по одному. Однако в данном случае он будет извлекать их из буфера.

С помощью классов FileReader и FileWriter выполняется ввод-вывод в текстовые файлы.

Метод ready() возвращает истину, если остались непрочитанные символы.

Читать и писать можно блоками. Также методу write() можно передать строку:

Рассматривая ввод данных с клавиатуры, мы уже использовали класс BufferedReader, который наследуется от Reader и позволяет читать отдельные строки методом readLine(). Его также можно использовать для построчного чтения файлов:

Я имею в виду, есть ли что-то эквивалентное этому в Java?:

если не. каков "оптимальный способ" сделать это.

Edit:
Я предпочитаю путь в стандартных библиотеках Java. Я не могу использовать сторонние библиотеки..

AFAIK, нет единого лайнера со стандартными библиотеками. Типичный подход со стандартными библиотеками будет примерно таким:

  • для того чтобы читать текст из файла, использовать FileInputStream
  • если производительность важна и Вы читаете большие файлы, было бы целесообразно обернуть поток в BufferedInputStream
  • поток должен быть закрыт абонент

но в стандартных классах java такой утилиты нет. Если вы (по какой-то причине) не хотите внешних библиотек, вам придется переопределить его. здесь некоторые примеры, и альтернативно, вы можете увидеть, как он реализуется commons-io или Guava.

не в основных библиотеках Java, но вы можете использовать гуавы:

или читать строки:

конечно, я уверен, что есть другие сторонние библиотеки, которые сделают это так же легко - я просто наиболее знаком с Guava.

Java 7 улучшает это жалкое состояние дел с Files класс (не путать с класс с тем же именем), вы можете получить все строки из файла - без внешних библиотек - с:

или в одну строку:

Если вам нужно что-то из коробки с чистым JDK, это отлично работает. Тем не менее, почему вы пишете Java без гуавы?

на Java 8 (без внешних библиотек) вы можете использовать потоки. Этот код считывает файл и помещает все строки, разделенные', ' в строку.

С помощью JDK / 11 вы можете прочитать полный файл на Path в виде строки с использованием Files.readString(Path path) :

документация метода из JDK гласит следующее:

внешние библиотеки не требуются. Содержимое файла будет буферизовано перед преобразованием в string.

вот 3 способа прочитать текстовый файл в одной строке, не требуя цикла. Я задокументировал 15 способов чтения из файла в Java а это из той статьи.

обратите внимание, что вам все равно придется перебирать список, который возвращается, даже если фактический вызов для чтения содержимого файла требует только 1 строки, без цикла.

1) java.НИО.файл.Файлы.readAllLines() - кодировка по умолчанию

2) Ява.НИО.файл.Файлы.readAllLines () - явная кодировка

внешние библиотеки не требуются. Содержимое файла будет буферизовано перед преобразованием в string.

Чтобы работать с файлами, есть шикарный утилитный класс — java.nio.file.Files . У него есть методы просто на все случаи жизни. Все методы этого класса статические и работают с объектами типа Path. Методов очень много, поэтому мы рассмотрим только основные:

Метод Описание
Создает новый файл с путем path
Создает новую директорию
Создает несколько директорий
Создает временный файл
Создает временную директорию
Удаляет файл или директорию, если она пуста
Копирует файл
Перемещает файл
Проверяет, что путь — это директория, а не файл
Проверяет, что путь — это файл, а не директория
Проверяет, что объект по заданному пути существует
Возвращает размер файла
Возвращает все содержимое файла в виде массива байт
Возвращает все содержимое файла в виде строки
Возвращает все содержимое файла в виде списка строк
Записывает в файл массив байт
Записывает в файл строку
Возвращает коллекцию файлов (и поддиректорий) из заданной директории

2. Создание файлов и директорий

Файлы и директории создавать очень просто. Убедимся на примерах:

Код Примечание
Создает файл
Создает директорию
Создает директорию и все нужные поддиректории, если их не существует.

3. Копирование, перемещение и удаление

Копировать, перемещать и удалять файлы так же легко. На директории это тоже распространяется, но они должны быть пустые.

Код Примечание
Копирует файл
Перемещает и переименовывает файл
Удаляет файл

4. Проверка типа файла и факта существования

Когда у вас есть какой-то путь, полученный извне, вы бы хотели знать, это файл или директория. Ну и вообще: существует такой файл/директория или нет?

Для этого тоже есть специальные методы. Так же можно легко узнать длину файла:

Код Примечание

5. Работа с содержимым файла

И наконец, есть целая серия методов, которые позволяют легко прочитать или записать содержимое файла. Пример:

snimok-ekrana-2016-11-16-v-21-25-22
snimok-ekrana-2016-11-16-v-21-35-19

*Это Говард Стивен Берг (Howard Stephen Berg), один из самых быстро читающих людей в мире 🙂 А FileWriter - Уильям Шекспир.

  • написана командой Vertex Academy. Надеемся, что она Вам будет полезна. Приятного прочтения!
  • это одна из статей из нашего "Самоучителя по Java"

Рассмотрим работу с FileWriter и FileReader:

  • с помощью FileWriter мы можем создавать файлы
  • с помощью FileReader - считывать их
Внимание:

Потоки FileWriter и FileReader немного отличаются от того, с чем мы встречались ранее. Работая с ними, понадобится всегда помнить 3 важных момента:

1. Объявление

Перед тем, как вызывать какие-нибудь методы для работы с файлами, нужно объявить FileWriter/FileReader:

snimok-ekrana-2016-11-17-v-17-07-25

snimok-ekrana-2016-11-17-v-17-10-14

Но Eclipse может не распознать FileReader/FileWriter и начнет ругаться. Если такое произойдет, посмотрите, импортировали ли вы библиотеку java.io.*. Для этого в самой первой строчке напишите:

2. Нужно закрыть поток

FileWriter/FileReader - это потоки, их нужно не только «открыть» (то-есть объявить), но и «закрыть» . Представьте, что Вы открыли кран. Нельзя же уйти из дому, оставив воду литься?

stocksnap_03f8a942c5

Это правило работает и для других потоков - кроме стандартных System.in и System.out.

Закрыть поток можно с помощью .close() :

public static void main ( String [ ] args ) throws Exception <

3. Допишите "волшебную фразу".

В программировании очень важна безопасность . А работа с FileWriter/FileReader - это небезопасно , в процессе может возникнуть масса разных ошибок. Это беспокоит Eclipse (или IntellijIdea - смотря чем пользуетесь), и программу она просто так не запустит. Помните, что к методу нужно дописать «throws Exception» :

Итак, еще раз акцентируем внимание - всегда Вы должны помнить о 3 моментах:

И еще, потоки FileWriter и FileReader воспринимают все файлы как текстовые:

snimok-ekrana-2016-11-16-v-21-44-24

FileWriter

Теперь представим, что Вы начинаете использовать FileWriter.

1. Объявление.

Как Вы помните, нужно не забыть импортировать библиотеки java.io.* и дописать "волшебную фразу" к методу, где Вы собираетесь объявить FileWriter.

Объявляем, как помните, почти как Scanner:

snimok-ekrana-2016-11-17-v-17-07-25

Объявили. А что теперь можно делать? Теперь пора пользоваться возможностями FileWriter!

Основной метод FileWriter - это метод .write() .

Мало? Да, но посмотрите, как много с ним можно сделать:

public static void main ( String [ ] args ) throws Exception < public static void newFile ( int k1 , int k2 ) throws Exception <

*обратите внимание - мы написали нашу "волшебную фразу" и в методе main, и в методе newFile.

Так мы можем записать числа от k1 до k2, от 2 до 9, в наш файл file1.txt. Можно записывать только четные или нечетные числа, какой-нибудь текст, и многое другое.

2. Переход на следующую строку

Но мы Вам кое-чего не сказали. Если запустить код из прошлого пункта, получится:

Если понадобится вывести числа в столбик, понадобится добавить " \n " от "new line", новая строка. Запишем в файл стих:

public static void main ( String [ ] args ) throws Exception < nFile . write ( "Хокку \nПодобен лучу самурайский клинок \nИ тот затупился \nПроклятая килька в томате!!" ) ;

Каждый раз, когда мы хотели, чтобы программа переходила на новую строку, мы ставили " \n ":

Теперь вы знаете, как вывести числа с новой строки:

public static void main ( String [ ] args ) throws Exception < public static void newFile ( int k1 , int k2 ) throws Exception <

3. Закрываем поток

После того, как Вы записали все необходимое, нужно не забыть закрыть поток. Это мы делали в каждом из приведенных примеров:

FileReader

Теперь, рассмотрим пошагово работу с FileReader.

1. Объявление

Сначала FileReader, как и FileWriter, нужно объявить . Не забудьте про библиотеку и " волшебную фразу ":

public static void main ( String [ ] args ) throws Exception <

2. FileReader + Scanner

Мы объявили не только FileReader, но и Scanner. Почему?

В отличии от FileWriter, FileReader не используется один:

2_shake
2_reader

Не вдаваясь в подробности, запомните, что FileReader и Scanner идут вместе. Но не забывайте их "связать" - для этого напишите название вашего объекта FileReader вместо "System.in" при объявлении Scanner:

3. Методы

Тут уже больше методов. Рассмотрим методы .nextLine() и .hasNextLine().

  • .nextLine() - это метод, который считывает строку (до ENTER), и возвращает это значение
  • .hasNextLine() - метод, который возвращает boolean - true или false, показывая, есть ли следующая строка.
public static void main ( String [ ] args ) throws Exception <

Должен быть такой результат:

Обратите внимание: мы используем .hasNextLine() для того, чтобы избежать ошибки, и не заставлять .nextLine() считывать строку, которой не существует:

snimok-ekrana-2016-11-22-v-19-11-15

snimok-ekrana-2016-11-22-v-19-11-15

4. Закрываем поток.

snimok-ekrana-2016-11-22-v-19-16-10

Готово. Теперь Вы знаете, как работать с FileWriter и FileReader.

Надеемся, что наша статья была Вам полезна. Также есть возможность записаться на наши курсы по Java в Киеве. Обучаем с нуля. Детальную информацию Вы можете найти у нас на сайте.

Читайте также: