Java — Потоки ввода/вывода, файлы и каталоги / ProgLang

Пакет java.io содержит почти каждый класс, который может потребоваться Вам для совершения ввода и вывода в Java. Все данные потоки представлены потоком ввода и адресом вывода. Поток в пакете java.io осуществляет поддержку различных данных, таких как примитивы, объекты, локализованные символы и т.д.

Содержание

  1. Потоки
  2. Байтовый поток
    1. Пример
  3. Символьные потоки
    1. Пример
  4. Стандартные потоки
    1. Пример
  5. Чтение и запись файла
  6. Поток FileInputStream – чтение из файла
  7. Поток FileOutputStream – создание и запись файла
    1. Пример
  8. Навигация по файловой системе и вводу/выводу
  9. Каталоги в Java
  10. Создание каталогов
    1. Пример
  11. Список файлов в папке
    1. Пример

    Потоки

    Потоки в Java определяются в качестве последовательности данных. Существует два типа потоков:

    • InPutStream – поток ввода используется для считывания данных с источника.
    • OutPutStream – поток вывода используется для записи данных по месту назначения.

    Java предоставляет сильную, но гибкую поддержку в отношении ввода/вывода, связанных с файлами и сетями, однако в данном руководстве рассмотрены лишь базовые функции, связанные с потоками и вводом/выводом. Рассмотрим далее по порядку наиболее распространенные примеры.

    Байтовый поток

    Потоки байтов в Java используются для осуществления ввода и вывода 8-битных байтов. Не смотря на множество классов, связанных с потоками байтов, наиболее распространено использование следующих классов: FileInputStream и FileOutputStream. Ниже рассмотрен пример, иллюстрирующий использование данных двух классов для копирования из одного файла в другой.

    Примечание по примеру: чтобы скопировать файл, необходимо в папке проекта создать файл file.txt с любым или пустым содержимым.

    Пример

    Теперь рассмотрим файл file.txt со следующим содержимым:

    В качестве следующего шага необходимо скомпилировать java-программу и выполнить ее, что позволит создать файл copied_file.txt с тем же содержимым, что имеется в file.txt. Таким образом, разместим обозначенный код в файле FileCopy.java и выполним следующее действие:

    Символьные потоки

    Потоки байтов в Java позволяют произвести ввод и вывод 8-битных байтов, в то время как потоки символов используются для ввода и вывода 16-битного юникода. Не смотря на множество классов, связанных с потоками символов, наиболее распространено использование следующих классов: FileReader и FileWriter. Не смотря на тот факт, что внутренний FileReader использует FileInputStream, и FileWriter использует FileOutputStream, основное различие состоит в том, что FileReader производит считывание двух байтов в конкретный момент времени, в то время как FileWriter производит запись двух байтов за то же время.

    Мы можем переформулировать представленный выше пример, в котором два данных класса используются для копирования файла ввода (с символами юникода) в файл вывода.

    Примечание по примеру: чтобы скопировать файл, необходимо в папке проекта создать файл file.txt с любым или пустым содержимым.

    Пример

    Теперь рассмотрим файл file.txt со следующим содержимым:

    В качестве следующего шага необходимо скомпилировать программу и выполнить ее, что позволит создать файл copied_file.txt с тем же содержимым, что имеется в file.txt. Таким образом, разместим обозначенный код в файле FileCopy.java и выполним следующее действие:

    Стандартные потоки

    Все языки программирования обеспечивают поддержку стандартного ввода/вывода, где программа пользователя может произвести ввод посредством клавиатуры и осуществить вывод на экран компьютера. Если вы знакомы с языками программирования C либо C++, вам должны быть известны три стандартных устройства STDIN, STDOUT и STDERR. Аналогичным образом, Java предоставляет следующие три стандартных потока:

    • Стандартный ввод – используется для перевода данных в программу пользователя, клавиатура обычно используется в качестве стандартного потока ввода, представленного в виде System.in.
    • Стандартный вывод – производится для вывода данных, полученных в программе пользователя, и обычно экран компьютера используется в качестве стандартного потока вывода, представленного в виде System.out.
    • Стандартная ошибка – используется для вывода данных об ошибке, полученной в программе пользователя, чаще всего экран компьютера служит в качестве стандартного потока сообщений об ошибках, представленного в виде System.err.

    Ниже представлена простая программа, которая создает InputStreamReader для чтения стандартного потока ввода, до введения пользователем «q»:

    Пример

    Разместим представленный выше код в файле ReadConsole.java и попробуем скомпилировать и выполнить его согласно тому, как это представлено в следующей программе. Данная программа продолжает чтение и вывод одного и того же символа до нажатия ‘q’:

    Чтение и запись файла

    Как было указано выше, поток представляет собой последовательность данных. InputStream используется для считывания данных с источника, OutputStream служит для записи данных по месту назначения.

    Ниже представлена иерархия классов для управления потоками Ввода и Вывода.

    В данном уроке нам предстоит рассмотреть два важных потока: FileInputStream и FileOutputStream.

    Поток FileInputStream – чтение из файла

    Поток FileInputStream – это поток, который используется в Java для чтения данных из файла. Объекты могут быть созданы при использовании ключевого слова new, доступны несколько типов конструкторов.

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

    Представленный ниже конструктор использует объектный файл с целью создания объекта входного потока для чтения файла. Сперва мы создаем объектный файл при использовании метода File() следующим образом:

    Теперь, получив объект InputStream, следует ознакомиться со следующим перечнем вспомогательных методов, которые могут быть использованы для считывания потока либо выполнения иных операций в потоке.

    Метод и описание
    1 public void close() throws IOException<>
    Данный метод в Java закрывает выходной файловый поток. Освобождает какие-либо системные ресурсы, связанные с файлом. Выдает IOException.
    2 protected void finalize()throws IOException <>
    Данный метод выполняет очистку соединения с файлом. Позволяет удостовериться в вызове закрытого метода данного выходного файлового потока при отсутствии каких-либо ссылок на данный поток. Выдает IOException.
    3 public int read(int r)throws IOException<>
    Данный метод осуществляет в Java считывание заданных байтов данных из InputStream. Возврат данных типа int. Возврат следующего байта данных, в конце файла будет произведен возврат к -1.
    4 public int read(byte[] r) throws IOException<>
    Данный метод производит считывание байтов r.length из входного потока в массив. Возврат общего числа считанных байтов. В конце файла будет произведен возврат к -1.
    5 public int available() throws IOException<>
    Выдает число байтов, которые могут быть считаны из входного файлового потока. Возврат данных типа int.

    Существуют также другие доступные входные потоки, более детальные сведения о которых представлены по следующим ссылкам:

    Поток FileOutputStream – создание и запись файла

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

    Далее представлены два конструктора, которые могут быть задействованы при создании объекта FileOutputStream.

    Представленный конструктор использует имя файла в качестве строки с целью создания объекта входного потока для записи файла в Java:

    Представленный ниже конструктор использует объектный файл с целью создания объекта выходного потока для записи файла. Сперва мы создаем объектный файл при использовании метода File() следующим образом:

    Теперь, получив объект OutputStream, следует ознакомиться со следующим перечнем вспомогательных методов, которые могут быть использованы для записи потока либо выполнения иных операций в потоке.

    Метод и описание
    1 public void close() throws IOException<>
    Данный метод в Java закрывает выходной файловый поток. Освобождает какие-либо системные ресурсы, связанные с файлом. Выдает IOException.
    2 protected void finalize()throws IOException <>
    Данный метод выполняет очистку соединения с файлом. Позволяет удостовериться в вызове закрытого метода данного выходного файлового потока при отсутствии каких-либо ссылок на данный поток. Выдает IOException.
    3 public void write(int w)throws IOException<>
    Данный метод осуществляет запись заданного байта в выходной поток.
    4 public void write(byte[] w)
    Запись байтов w.length из указанного массива байтов в OutputStream.

    Существуют также другие доступные выходные потоки, более детальные сведения о которых представлены по следующим ссылкам:

    Пример

    В следующем примере представлены InputStream и OutputStream – потоки для чтения, создания и записи файла:

    Представленный выше java-код создаст файл file.txt и пропишет заданные символы в формате char. То же самое будет выводиться на экран стандартного вывода.

    Навигация по файловой системе и вводу/выводу

    Существует ряд других классов, которые нам предстоит рассмотреть с целью ознакомления с основами навигации в файловой системе и вводу/выводу.

    Каталоги в Java

    В Java каталог представлен Файлом, который может содержать список других файлов и каталогов. Используя объект File, вы можете создать каталог, прокрутить список файлов, представленных в каталоге. Для получения более детальных сведений, ознакомьтесь с перечнем всех методов, которые могут быть вызваны из объекта File, будучи связанными с каталогами.

    Создание каталогов

    Существуют два служебных метода File, которые могут быть использованы для создания каталогов:

    • Метод mkdir() позволяет создать папку в Java, возвращая значение true при успехе операции, и false в случае сбоя. Сбой свидетельствует о том, что путь указанный в объекте File уже существует, либо что каталог не может быть создан в связи с тем, что полный путь еще не существует.
    • Метод mkdirs() создает каталог и все вышестоящие каталоги.

    В следующем примере представлено создание папки «/java/proglang/newdir»:

    Пример

    Скомпилируйте и выполните следующий код для создания каталога «/java/proglang/newdir».

    Примечание ? Java автоматически формирует разделители пути в UNIX и Windows с учетом соглашений. При использовании косой черты (/) при работе с Java в системе Windows, производится корректное разрешение пути.

    Список файлов в папке

    Метод list(), представленный объектом File, может быть использован для предоставления перечня всех файлов и каталогов, имеющихся в заданной папке, в следующем виде:

    Пример

    Вследствие этого будет получен следующий результат, основанный на каталогах и файлах, доступных в вашем каталоге /NetBeans 8.2/Projects/ReadDirectory/ReadDirectory/:

    Чтение и запись файлов

    В 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. FileWriter и FileReader

    *Это Говард Стивен Берг (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() :

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

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

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

    1. Объявить
    2. Не забыть закрыть поток
    3. Дописать «throws Exception»

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

    FileWriter

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    FileReader

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

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

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

    2. FileReader + Scanner

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

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

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

    3. Методы

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

    • .nextLine() — это метод, который считывает строку (до ENTER), и возвращает это значение
    • .hasNextLine() — метод, который возвращает boolean — true или false, показывая, есть ли следующая строка.

    Система ввода/вывода

    Java имеет в своём составе множество классов, связанных с вводом/выводом данных. Рассмотрим некоторые из них.

    Класс File

    В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу. А также осуществлять навигацию по иерархиям подкаталогов.

    Подробнее о классе java.io.File

    Поток

    При работе с данными ввода/вывода вам будет часто попадаться термин Поток (Stream). Поток — это абстрактное значение источника или приёмника данных, которые способны обрабатывать информацию. Вы в реальности не видите, как действительно идёт обработка данных в устройствах ввода/вывода, так как это сложно и вам это не нужно. Это как с телевизором — вы не знаете, как сигнал из кабеля превращается в картинку на экране, но вполне можете переключаться между каналами через пульт.

    Есть два типа потоков: байтовые и символьные. В некоторых ситуациях символьные потоки более эффективны, чем байтовые.

    За ввод и вывод отвечают разные классы Java. Классы, производные от базовых классов InputStream или Reader, имеют методы с именами read() для чтения отдельных байтов или массива байтов (отвечают за ввод данных). Классы, производные от классов OutputStream или Write, имеют методы с именами write() для записи одиночных байтов или массива байтов (отвечают за вывод данных).

    Подробнее о классе InputStream

    Класс OutputStream

    Класс OutputStream — это абстрактный класс, определяющий потоковый байтовый вывод.

    В этой категории находятся классы, определяющие, куда направляются ваши данные: в массив байтов (но не напрямую в String; предполагается что вы сможете создать их из массива байтов), в файл или канал.

    BufferedOutputStream Буферизированный выходной поток ByteArrayOutputStream Создает буфер в памяти. Все данные, посылаемые в этот поток, размещаются в созданном буфере DataOutputStream Выходной поток, включающий методы для записи стандартных типов данных Java FileOutputStream Отправка данных в файл на диске. Реализация класса OutputStream ObjectOutputStream Выходной поток для объектов PipedOutputStream Реализует понятие выходного канала. FilterOutputStream Абстрактный класс, предоставляющий интерфейс для классов-надстроек, которые добавляют к существующим потокам полезные свойства.

    • int close() — закрывает выходной поток. Следующие попытки записи передадут исключение IOException
    • void flush() — финализирует выходное состояние, очищая все буферы вывода
    • abstract void write (int oneByte) — записывает единственный байт в выходной поток
    • void write (byte[] buffer) — записывает полный массив байтов в выходной поток
    • void write (byte[] buffer, int offset, int count) — записывает диапазон из count байт из массива, начиная с смещения offset

    BufferedOutputStream

    Класс BufferedOutputStream не сильно отличается от класса OutputStream, за исключением дополнительного метода flush(), используемого для обеспечения записи данных в буферизируемый поток. Буферы вывода нужно для повышения производительности.

    ByteArrayOutputStream

    Класс ByteArrayOutputStream использует байтовый массив в выходном потоке. Метод close() можно не вызывать.

    DataOutputStream

    Класс DataOutputStream позволяет писать элементарные данные в поток через интерфейс DataOutput, который определяет методы, преобразующие элементарные значения в форму последовательности байтов. Такие потоки облегчают сохранение в файле двоичных данных.

    Класс DataOutputStream расширяет класс FilterOutputStream, который в свою очередь, расширяет класс OutputStream.

    Методы интерфейса DataOutput:

    • writeDouble(double value)
    • writeBoolean(boolean value)
    • writeInt(int value)

    FileOutputStream

    Класс FileOutputStream создаёт объект класса OutputStream, который можно использовать для записи байтов в файл. Создание нового объекта не зависит от того, существует ли заданный файл, так как он создаёт его перед открытием. В случае попытки открытия файла, доступного только для чтения, будет передано исключение.

    Классы символьных потоков

    Символьные потоки имеют два основных абстрактных класса Reader и Writer, управляющие потоками символов Unicode.

    Reader

    Методы класса Reader:

    • abstract void close() — закрывает входной поток. Последующие попытки чтения передадут исключение IOException
    • void mark(int readLimit) — помещает метку в текущую позицию во входном потоке
    • boolean markSupported() — возвращает true, если поток поддерживает методы mark() и reset()
    • int read() — возвращает целочисленное представление следующего доступного символа вызывающего входного потока. При достижении конца файла возвращает значение -1. Есть и другие перегруженные версии метода
    • boolean ready() — возвращает значение true, если следующий запрос не будет ожидать.
    • void reset() — сбрасывает указатель ввода в ранее установленную позицию метки
    • logn skip(long charCount) — пропускает указанное число символов ввода, возвращая количество действительно пропущенных символов

    BufferedReader Буферизированный входной символьный поток CharArrayReader Входной поток, который читает из символьного массива FileReader Входной поток, читающий файл FilterReader Фильтрующий читатель InputStreamReader Входной поток, транслирующий байты в символы LineNumberReader Входной поток, подсчитывающий строки PipedReader Входной канал PushbackReader Входной поток, позволяющий возвращать символы обратно в поток Reader Абстрактный класс, описывающий символьный ввод StringReader Входной поток, читающий из строки

    Класс BufferedReader

    Класс BufferedReader увеличивает производительность за счёт буферизации ввода.

    Класс CharArrayReader

    Класс CharArrayReader использует символьный массив в качестве источника.

    Класс FileReader

    Класс FileReader, производный от класса Reader, можно использовать для чтения содержимого файла. В конструкторе класса нужно указать либо путь к файлу, либо объект типа File.

    Writer

    Класс Writer — абстрактный класс, определяющий символьный потоковый вывод. В случае ошибок все методы класса передают исключение IOException.

    • Writer append(char c) — добавляет символ в конец вызывающего выходного потока. Возвращает ссылку на вызывающий поток
    • Writer append(CharSequence csq) — добавляет символы в конец вызывающего выходного потока. Возвращает ссылку на вызывающий поток
    • Writer append(CharSequence csq, int start, int end) — добавляет диапазон символов в конец вызывающего выходного потока. Возвращает ссылку на вызывающий поток
    • abstract void close() — закрывает вызывающий поток
    • abstract void flush() — финализирует выходное состояние так, что все буферы очищаются
    • void write(int oneChar) — записывает единственный символ в вызывающий выходной поток. Есть и другие перегруженные версии метода

    BufferedWriter Буферизированный выходной символьный поток CharArrayWriter Выходной поток, который пишет в символьный массив FileWriter Выходной поток, пишущий в файл FilterWriter Фильтрующий писатель OutputStreamWriter Выходной поток, транслирующий байты в символы PipedWriter Выходной канал PrintWriter Выходной поток, включающий методы print() и println() StringWriter Выходной поток, пишущий в строку Writer Абстрактный класс, описывающий символьный вывод

    Класс BufferedWriter

    Класс BufferedWriter — это класс, производный от класса Writer,который буферизует вывод. С его помощью можно повысить производительность за счёт снижения количества операций физической записи в выходное устройство.

    Класс CharArrayWriter

    Класс CharArrayWriter использует массив для выходного потока.

    Класс FileWriter

    Класс FileWriter создаёт объект класса, производного от класса Writer, который вы можете применять для записи файла. Есть конструкторы, которые позволяют добавить вывод в конец файла. Создание объекта не зависит от наличия файла, он будет создан в случае необходимости. Если файл существует и он доступен только для чтения, то передаётся исключение IOException.

    Чтение и запись файлов

    Существует множество классов и методов для чтения и записи файлов. Наиболее распространённые из них — классы FileInputStream и FileOutputStream, которые создают байтовые потоки, связанные с файлами. Чтобы открыть файл, нужно создать объект одного из этих файлов, указав имя файла в качестве аргумента конструктора.

    В filename нужно указать имя файла, который вы хотите открыть. Если при создании входного потока файл не существует, передаётся исключение FileNotFoundException. Аналогично для выходных потоков, если файл не может быть открыт или создан, также передаётся исключение. Сам класс исключения происходит от класса IOException. Когда выходной файл открыт, любой ранее существовавший файл с тем же именем уничтожается.

    После завершения работы с файлом, его необходимо закрыть с помощью метода close() для освобождения системных ресурсов. Незакрытый файл приводит к утечке памяти.

    В JDK 7 метод close() определяется интерфейсом AutoCloseable и можно явно не закрывать файл, а использовать новый оператор try-с-ресурсами, что для Android пока не слишком актуально.

    Чтобы читать файл, нужно вызвать метод read(). Когда вызывается этот метод, он читает единственный байт из файла и возвращает его как целое число. Когда будет достигнут конец файла, то метод вернёт значение -1. Примеры использования методов есть в различных статьях на сайте.

    Иногда используют вариант, когда метод close() помещается в блок finally. При таком подходе все методы, которые получают доступ к файлу, содержатся в пределах блока try, а блок finally используется для закрытия файла. Таким образом, независимо от того, как закончится блок try, файл будет закрыт.

    Так как исключение FileNotFoundException является подклассом IOException, то не обязательно обрабатывать два исключения отдельно, а оставить только IOException, если вам не нужно отдельно обрабатывать разные причины неудачного открытия файла. Например, если пользователь вводит вручную имя файла, то более конкретное исключение будет к месту.

    Для записи в файл используется метод write().

    Метод пишет в файл байт, переданный параметром value. Хотя параметр объявлена как целочисленный, в файл записываются только младшие восемь бит. При ошибке записи передаётся исключение.

    В JDK 7 есть способ автоматического управления ресурсами:

    Когда в Android будет полноценная поддержка JDK 7, то дополним материал.

    Буферизированное чтение из файла — BufferedReader

    Чтобы открыть файл для посимвольного чтения, используется класс FileInputReader; имя файла задаётся в виде строки (String) или объекта File. Ускорить процесс чтения помогает буферизация ввода, для этого полученная ссылка передаётся в конструктор класса BufferedReader. Так как в интерфейсе класса имеется метод readLine(), все необходимое для чтения имеется в вашем распоряжении. При достижении конца файла метод readLine() возвращает ссылку null.

    Вывод в файл — FileWriter

    Объект FileWriter записывает данные в файл. При вводе/выводе практически всегда применяется буферизация, поэтому используется BufferedWriter.

    Когда данные входного потока исчерпываются, метод readLine() возвращает null. Для потока явно вызывается метод close(); если не вызвать его для всех выходных файловых потоков, в буферах могут остаться данные, и файл получится неполным.

    Сохранение и восстановление данных — PrintWriter

    PrintWriter форматирует данные так, чтобы их мог прочитать человек. Однако для вывода информации, предназначенной для другого потока, следует использовать классы DataOutputStream для записи данных и DataInputStream для чтения данных.

    Единственным надежным способом записать в поток DataOutputStream строку так, чтобы ее можно было потом правильно считать потоком DataInputStream, является кодирование UTF-8, реализуемое методами readUTF() и writeUTF(). Эти методы позволяют смешивать строки и другие типы данных, записываемые потоком DataOutputStream, так как вы знаете, что строки будут правильно сохранены в Юникоде и их будет просто воспроизвести потоком DataInputStream.

    Метод writeDouble() записывает число double в поток, а соответствующий ему метод readDouble() затем восстанавливает его (для других типов также существуют подобные методы).

    RandomAccessFile — Чтение/запись файлов с произвольным доступом

    Работа с классом RandomAccessFile напоминает использование совмещенных в одном классе потоков DataInputStream и DataOutputStream (они реализуют те же интерфейсы DataInput и DataOutput). Кроме того, метод seek() позволяет переместиться к определенной позиции и изменить хранящееся там значение.

    При использовании RandomAccessFile необходимо знать структуру файла. Класс RandomAccessFile содержит методы для чтения и записи примитивов и строк UTF-8.

    RandomAccessFile может открываться в режиме чтения («r») или чтения/записи («rw»). Также есть режим «rws», когда файл открывается для операций чтения-записи и каждое изменение данных файла немедленно записывается на физическое устройство.

    Исключения ввода/вывода

    В большинстве случаев у классов ввода/вывода используется исключение IOException. Второе исключение FileNotFoundException передаётся в тех случаях, когад файл не может быть открыт. Данное исключение происходит от IOException, поэтому оба исключения можно обрабатывать в одном блоке catch, если у вас нет нужды обрабатывать их по отдельности.

    Дополнительное чтение

    Используем AsyncTask для загрузки текстового файла из сети — используются BufferedReader, InputStreamReader, InputStream.

    Различные способы чтения текстового файла в Java

    Есть несколько способов написания и чтения текстового файла. это требуется при работе со многими приложениями.

    Существует несколько способов чтения простого текстового файла в Java, например, вы можете использовать FileReader , BufferedReader или Scanner для чтения текстового файла. Каждая утилита предоставляет что-то особенное, например, BufferedReader обеспечивает буферизацию данных для быстрого чтения, а Scanner предоставляет возможность анализа.

    Мы также можем использовать BufferReader и Scanner для построчного чтения текстового файла в Java. Затем Java SE 8 представляет другой класс Stream java.util.stream.Stream, который обеспечивает ленивый и более эффективный способ чтения файла.

    Примечание : здесь были исключены обычные практики написания хорошего кода, такие как очистка / закрытие потоков, обработка исключений и т. Д., Для лучшего понимания кодов новичками.

    Вот несколько способов чтения файлов:

      Использование BufferedReader: этот метод читает текст из потока ввода символов. Он выполняет буферизацию для эффективного чтения символов, массивов и строк.
      Размер буфера может быть указан, или размер по умолчанию может быть использован. Значение по умолчанию достаточно велико для большинства целей.

    Как правило, каждый запрос чтения, сделанный устройством чтения, вызывает соответствующий запрос чтения основного символа или потока байтов. Поэтому желательно обернуть BufferedReader вокруг любого Reader, чьи операции read () могут быть дорогостоящими, например FileReaders и InputStreamReaders. Например,

    // Java-программа для иллюстрации чтения из FileReader
    // используя BufferedReader

    public class ReadFromFile2

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

    // Нам нужно указать путь к файлу в качестве параметра:

    // двойная обратная кавычка, чтобы избежать интерпретации компилятором слов

    // like / test as / t (т.е. как escape-последовательность)

    File file = new File( «C:\Users\pankaj\Desktop\test.txt» );

    BufferedReader br = new BufferedReader( new FileReader(file));

    while ((st = br.readLine()) != null )

    Использование класса FileReader: удобный класс для чтения файлов символов. Конструкторы этого класса предполагают, что кодировка символов по умолчанию и размер байтового буфера по умолчанию являются подходящими.
    Конструкторы, определенные в этом классе:

    // Java-программа для иллюстрации чтения из
    // FileReader с использованием FileReader

    public class ReadingFromFile

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

    // передать путь к файлу в качестве параметра

    new FileReader( «C:\Users\pankaj\Desktop\test.txt» );

    while ((i=fr.read()) != — 1 )

    System.out.print(( char ) i);

    Использование класса Scanner: простой текстовый сканер, который может анализировать примитивные типы и строки с помощью регулярных выражений.
    Сканер разбивает свои входные данные на токены, используя шаблон разделителя, который по умолчанию соответствует пробелу. Полученные токены могут затем быть преобразованы в значения различных типов с использованием различных следующих методов.

    // Java-программа для иллюстрации чтения из текстового файла
    // используя класс сканера

    public class ReadFromFileUsingScanner

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

    // передать путь к файлу в качестве параметра

    new File( «C:\Users\pankaj\Desktop\test.txt» );

    Scanner sc = new Scanner(file);

    Используя класс Scanner, но без использования циклов :

    // Java-программа для иллюстрации чтения из FileReader
    // используя класс сканера для чтения всего файла
    // без использования цикла

    public class ReadingEntireFileWithoutLoop

    public static void main(String[] args)

    File file = new File( «C:\Users\pankaj\Desktop\test.txt» );

    Scanner sc = new Scanner(file);

    // нам просто нужно использовать // Z в качестве разделителя

    Чтение всего файла в списке: чтение всех строк из файла. Этот метод гарантирует, что файл будет закрыт, когда все байты были прочитаны или будет выдана ошибка ввода-вывода или другое исключение во время выполнения. Байты из файла декодируются в символы с использованием указанной кодировки.

    Этот метод распознает следующее как терминаторы строки:

    // Java-программа для иллюстрации чтения данных из файла
    // используя nio.File

    public class ReadFileIntoList

    public static List readFileInList(String fileName)

Adblock
detector