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. Работа с содержимым файла
И наконец, есть целая серия методов, которые позволяют легко прочитать или записать содержимое файла. Пример:
*Это Говард Стивен Берг (Howard Stephen Berg), один из самых быстро читающих людей в мире 🙂 А FileWriter - Уильям Шекспир.
- написана командой Vertex Academy. Надеемся, что она Вам будет полезна. Приятного прочтения!
- это одна из статей из нашего "Самоучителя по Java"
Рассмотрим работу с FileWriter и FileReader:
- с помощью FileWriter мы можем создавать файлы
- с помощью FileReader - считывать их
Внимание:
Потоки FileWriter и FileReader немного отличаются от того, с чем мы встречались ранее. Работая с ними, понадобится всегда помнить 3 важных момента:
1. Объявление
Перед тем, как вызывать какие-нибудь методы для работы с файлами, нужно объявить FileWriter/FileReader:
Но Eclipse может не распознать FileReader/FileWriter и начнет ругаться. Если такое произойдет, посмотрите, импортировали ли вы библиотеку java.io.*. Для этого в самой первой строчке напишите:
2. Нужно закрыть поток
FileWriter/FileReader - это потоки, их нужно не только «открыть» (то-есть объявить), но и «закрыть» . Представьте, что Вы открыли кран. Нельзя же уйти из дому, оставив воду литься?
Это правило работает и для других потоков - кроме стандартных System.in и System.out.
Закрыть поток можно с помощью .close() :
public static void main ( String [ ] args ) throws Exception <3. Допишите "волшебную фразу".
В программировании очень важна безопасность . А работа с FileWriter/FileReader - это небезопасно , в процессе может возникнуть масса разных ошибок. Это беспокоит Eclipse (или IntellijIdea - смотря чем пользуетесь), и программу она просто так не запустит. Помните, что к методу нужно дописать «throws Exception» :
Итак, еще раз акцентируем внимание - всегда Вы должны помнить о 3 моментах:
И еще, потоки FileWriter и FileReader воспринимают все файлы как текстовые:
FileWriter
Теперь представим, что Вы начинаете использовать FileWriter.
1. Объявление.
Как Вы помните, нужно не забыть импортировать библиотеки java.io.* и дописать "волшебную фразу" к методу, где Вы собираетесь объявить FileWriter.
Объявляем, как помните, почти как Scanner:
Объявили. А что теперь можно делать? Теперь пора пользоваться возможностями 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 не используется один:
Не вдаваясь в подробности, запомните, что FileReader и Scanner идут вместе. Но не забывайте их "связать" - для этого напишите название вашего объекта FileReader вместо "System.in" при объявлении Scanner:
3. Методы
Тут уже больше методов. Рассмотрим методы .nextLine() и .hasNextLine().
- .nextLine() - это метод, который считывает строку (до ENTER), и возвращает это значение
- .hasNextLine() - метод, который возвращает boolean - true или false, показывая, есть ли следующая строка.
Должен быть такой результат:
Обратите внимание: мы используем .hasNextLine() для того, чтобы избежать ошибки, и не заставлять .nextLine() считывать строку, которой не существует:
4. Закрываем поток.
Готово. Теперь Вы знаете, как работать с FileWriter и FileReader.
Надеемся, что наша статья была Вам полезна. Также есть возможность записаться на наши курсы по Java в Киеве. Обучаем с нуля. Детальную информацию Вы можете найти у нас на сайте.
Читайте также: