Система ввода/вывода
Java имеет в своём составе множество классов, связанных с вводом/выводом данных.
Поток
При работе с данными ввода/вывода вам будет часто попадаться термин Поток (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
Класс 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
Класс BufferedWriter — это класс, производный от класса Writer,который буферизует вывод. С его помощью можно повысить производительность за счёт снижения количества операций физической записи в выходное устройство.
Класс CharArrayWriter
Класс CharArrayWriter использует массив для выходного потока.
Класс FileWriter
Класс FileWriter создаёт объект класса, производного от класса Writer, который вы можете применять для записи файла. Есть конструкторы, которые позволяют добавить вывод в конец файла. Создание объекта не зависит от наличия файла, он будет создан в случае необходимости. Если файл существует и он доступен только для чтения, то передаётся исключение IOException.
Класс File
В отличие от большинства классов ввода/вывода, класс File работает не с потоками, а непосредственно с файлами. Данный класс позволяет получить информацию о файле: права доступа, время и дата создания, путь к каталогу. А также осуществлять навигацию по иерархиям подкаталогов.
Подробнее о классе java.io.File
Чтение и запись файлов
Существует множество классов и методов для чтения и записи файлов. Наиболее распространённые из них — классы FileInputStream и FileOutputStream, которые создают байтовые потоки, связанные с файлами. Чтобы открыть файл, нужно создать объект одного из этих файлов, указав имя файла в качестве аргумента конструктора.
FileInputStream(String filename) throws FileNotFoundException FileOutputStream(String filename) throws FileNotFoundException
В filename нужно указать имя файла, который вы хотите открыть. Если при создании входного потока файл не существует, передаётся исключение FileNotFoundException. Аналогично для выходных потоков, если файл не может быть открыт или создан, также передаётся исключение. Сам класс исключения происходит от класса IOException. Когда выходной файл открыт, любой ранее существовавший файл с тем же именем уничтожается.
После завершения работы с файлом, его необходимо закрыть с помощью метода close() для освобождения системных ресурсов. Незакрытый файл приводит к утечке памяти.
В JDK 7 метод close() определяется интерфейсом AutoCloseable и можно явно не закрывать файл, а использовать новый оператор try-с-ресурсами, что для Android пока не слишком актуально.
Чтобы читать файл, нужно вызвать метод read(). Когда вызывается этот метод, он читает единственный байт из файла и возвращает его как целое число. Когда будет достигнут конец файла, то метод вернёт значение -1. Примеры использования методов есть в различных статьях на сайте.
Иногда используют вариант, когда метод close() помещается в блок finally. При таком подходе все методы, которые получают доступ к файлу, содержатся в пределах блока try, а блок finally используется для закрытия файла. Таким образом, независимо от того, как закончится блок try, файл будет закрыт.
Так как исключение FileNotFoundException является подклассом IOException, то не обязательно обрабатывать два исключения отдельно, а оставить только IOException, если вам не нужно отдельно обрабатывать разные причины неудачного открытия файла. Например, если пользователь вводит вручную имя файла, то более конкретное исключение будет к месту.
Для записи в файл используется метод write().
void write(int value) throws IOException
Метод пишет в файл байт, переданный параметром value. Хотя параметр объявлена как целочисленный, в файл записываются только младшие восемь бит. При ошибке записи передаётся исключение.
В JDK 7 есть способ автоматического управления ресурсами:
try (спецификация_ресурса) < // использование ресурса >
Когда в 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 I/O
IO API — (Input & Output) в первую очередь это Java API, которые облегчают работу с потоками.
Очень часто приходится получать какой-то поток данных, а потом как-то их обрабатывать и отправлять дальше. Например, пользователь ввел логин и пароль, программа в свою очередь должна получить эти данные, обработать и сохранить в файл. Для этих целей можно использовать IO.
В Java библиотека IO API находится в пакете java.io.
Java Non-blocking I/O (иногда — Java New I/O, «новый ввод-вывод») — коллекция прикладных программных интерфейсов для языка Java, предназначенных для реализации высокопроизводительных операций ввода-вывода. Первая реализация появилась с J2SE версии 1.4 от Sun Microsystems как альтернатива стандартным операциям ввода-вывода.
Вопросы для прохождения интервью на позицию Java разработчик
6059 Total Views 2 Views Today
Views: 5 550
Добавить комментарий Отменить ответ
Для отправки комментария вам необходимо авторизоваться.
Java. IO Пространство имен
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Классы
добавляет BufferedInputStream функциональные возможности для другого входного потока, а именно возможность буферизации входных данных и поддержки mark методов и reset .
Класс реализует буферизованного выходного потока.
Считывает текст из входного символьного потока, буферизируя символы таким образом, чтобы обеспечить эффективное чтение символов, массивов и строк.
Записывает текст в поток вывода символов, буферизируя символы, чтобы обеспечить эффективную запись отдельных символов, массивов и строк.
Содержит ByteArrayInputStream внутренний буфер, содержащий байты, которые могут быть считаны из потока.
Этот класс реализует поток вывода, в котором данные записываются в массив байтов.
Этот класс реализует буфер символов, который можно использовать в качестве потока ввода символов.
Этот класс реализует буфер символов, который можно использовать в качестве модуля записи.
Базовый класс для исключений преобразования символов.
Методы доступа к консольному устройству на основе символов, если таковые есть, связанному с текущей виртуальной машиной Java.
Поток входных данных позволяет приложению считывать примитивные типы данных Java из базового входного потока способом, не зависящим от компьютера.
Поток вывода данных позволяет приложению записывать примитивные типы данных Java в поток вывода переносимым способом.
Сигнализирует о неожиданном достижении конца файла или потока во время ввода.
Абстрактное представление имен путей к файлам и каталогам.
Экземпляры класса дескриптора файла служат непрозрачным дескриптором для базовой структуры компьютера, представляющей открытый файл, открытый сокет или другой источник или приемник байтов.
получает FileInputStream входные байты из файла в файловой системе.
Сигнализирует о сбое попытки открыть файл, обозначенный указанным именем пути.
Поток вывода файлов — это выходной поток для записи данных в File или в FileDescriptor .
Устаревший код безопасности; не использовать.
Считывает текст из символьных файлов, используя размер буфера по умолчанию.
Записывает текст в символьные файлы, используя размер буфера по умолчанию.
Содержит FilterInputStream другой входной поток, который используется в качестве основного источника данных, возможно, преобразовывает данные по пути или предоставляет дополнительные функциональные возможности.
Этот класс является суперклассом всех классов, которые фильтруют потоки вывода.
Абстрактный класс для чтения отфильтрованных потоков символов.
Абстрактный класс для записи отфильтрованных потоков символов.
Этот абстрактный класс является суперклассом всех классов, представляющих входной поток байтов.
InputStreamReader — это мост от байтовых потоков к потокам символов: он считывает байты и декодирует их в символы с помощью указанного java.nio.charset.Charset charset .
Сообщает, что операция ввода-вывода была прервана.
Возникает, когда среда выполнения сериализации обнаруживает одну из следующих проблем с классом.
Указывает, что один или несколько десериализованных объектов не прошли проверочные тесты.
Возникает при возникновении серьезной ошибки ввода-вывода.
Сигнализирует о возникновении какого-либо исключения ввода-вывода.
Этот класс представляет собой фильтр входного потока, который предоставляет дополнительные функции отслеживания текущего номера строки.
Буферизованный поток ввода символов, который отслеживает номера строк.
Возникает, если сериализация или десериализация не активна.
Возникает, когда экземпляру требуется сериализуемый интерфейс.
ObjectInputStream десериализует примитивные данные и объекты, ранее записанные с помощью ObjectOutputStream.
Предоставьте доступ к постоянным полям, считываемым из входного потока.
ObjectOutputStream записывает примитивные типы данных и графы объектов Java в OutputStream.
Предоставьте программный доступ к постоянным полям для записи в ObjectOutput.
Дескриптор сериализации для классов.
Вспомогательный интерфейс с константами, используемыми реализацией сериализации.
Суперкласс всех исключений, относящихся к классам Object Stream.
Описание сериализуемого поля из класса Serializable.
Исключение, указывающее на сбой операции чтения объекта из-за непрочитанных примитивных данных или конец данных, принадлежащих сериализованному объекту в потоке.
Этот абстрактный класс является суперклассом всех классов, представляющих выходной поток байтов.
OutputStreamWriter — это мост от потоков символов к потокам байтов. Символы, записанные в него, кодируются в байты с помощью указанного java.nio.charset.Charset charset .
Поток входных данных по каналу должен быть подключен к потоку вывода по каналу; поток входных данных, передаваемый по конвейеру, затем предоставляет все байты данных, записанные в поток вывода по каналу.
Поток вывода, передаваемый по каналу, можно подключить к потоку входных данных, чтобы создать канал связи.
Потоки ввода символов по конвейеру.
Потоки символьного вывода по конвейеру.
добавляет PrintStream функциональные возможности в другой поток вывода, а именно возможность удобно печатать представления различных значений данных.
Выводит форматированные представления объектов в поток вывода текста.
добавляет PushbackInputStream функциональные возможности в другой входной поток, а именно возможность «отодвинуть» или «непрочитанные» байты, сохраняя обратно отправляемые байты во внутреннем буфере.
Средство чтения потока символов, которое позволяет возвращать символы в поток.
Экземпляры этого класса поддерживают чтение и запись в файл произвольного доступа.
Абстрактный класс для чтения потоков символов.
Представляет SequenceInputStream логическое объединение других входных потоков.
Эта устаревшая безопасность не поддерживается в Android.
Возникает, когда сведения об элементе управления, считанные из потока объектов, нарушают внутренние проверки согласованности.
Класс StreamTokenizer принимает входной поток и анализирует его в «токены», позволяя считывать маркеры по одному за раз.
Этот класс позволяет приложению создать входной поток, в котором считываемые байты предоставляются содержимым строки.
Поток символов, источником которого является строка.
Поток символов, который собирает свои выходные данные в буфер строки, который затем можно использовать для создания строки.
Сигнализирует о сбое операции синхронизации.
Заключает в оболочку IOException с незаверяемым исключением.
Кодировка символов не поддерживается.
Сигнализирует о том, что строка неправильного формата в «DataInput.
Сигнализирует о том, что во время операции записи было вызвано одно из исключений ObjectStreamException.
Абстрактный класс для записи в потоки символов.
Интерфейсы
— Closeable это источник или назначение данных, которые можно закрыть.
Интерфейс DataInput позволяет считывать байты из двоичного потока и восстанавливать из них данные в любом из примитивных типов Java.
Интерфейс DataOutput обеспечивает преобразование данных из любого из примитивных типов Java в последовательность байтов и запись этих байтов в двоичный поток.
Только удостоверение класса экземпляра Externalizable записывается в поток сериализации, и класс отвечает за сохранение и восстановление содержимого своих экземпляров.
Фильтр для абстрактных имен путей.
Экземпляры классов, реализующих этот интерфейс, используются для фильтрации имен файлов.
— Flushable это назначение данных, которые могут быть сброшены.
ObjectInput расширяет интерфейс DataInput, включив в него чтение объектов.
Интерфейс обратного вызова для проверки объектов в графе.
ObjectOutput расширяет интерфейс DataOutput, включая запись объектов.
Константы, записанные в поток сериализации объектов.
Сериализуемость класса включается классом, реализующим java.
Перечисления
Перечисляет значения, возвращаемые несколькими типами и принимаемые в качестве параметра члена F:Java.IO.ObjectOutputStream.UseProtocolVersion .
Перечисляет значения, возвращаемые несколькими типами.
Урок 1. Введение в Java IO

Хочу вам представить первую серию уроков на сайте, а именно серию уроков по Java IO. В этом уроке я вас познакомлю с Java IO API для чего он нужен и чем он вам поможет.
Сразу же хочу сказать читателям, которые слышали о Java NIO, то что немного позже будет и по Java NIO API серия уроков, просто для начинающих я думаю будет полезно знать и о IO API.
О Java IO
IO API – (Input & Output) в первую очередь это Java API, которые облегчают работу с потоками.
Очень часто приходится получать какой-то поток данных, а потом как-то их обрабатывать и отправлять дальше. Например, пользователь ввел логин и пароль, программа в свою очередь должна получить эти данные, обработать и сохранить в файл. Для этих целей можно использовать IO.
В Java библиотека IO API находится в пакете java.io и для того чтобы начать использовать IO достаточно импортировать данную библиотеку в ваш класс.
Input and Output – Назначение
В java.io существуют так называемые потоки ввода и вывода (InputStream and OutputStream).
В основном java.io предназначен для чтения и записи данных в ресурс:
2) при работе с сетевым подключением;
3) System.err, System.in, System.out;
4) при работе с буфером.
Процесс чтения данных из ресурса и запись их в назначенное место показан на рисунку ниже.

Программа которая должна считать данные с потока и записать в поток показана на рисунке ниже.

Как видите в этом случае Ресурс связан с InputStream /Reader, а он в свою очередь связан с программой и через него программа получает поток данных.
Программа связанна с OutputStream / Writer, и с его помощью записываем данные которые отдала программа в Destination.
Java IO – Способности
В Java IO много классов которые в основном работают с потоками чтения и записи, и решают различные задачи:
– получения доступа к файлам;
– получение сетевого соединения;
– работа с буфером;
– доступ к внутринему буферу памяти;
– чтение и запись текста;
– чтение и запись примитивных данных (long, int, float …);
– чтение и запись объектов.
Все эти возможности вам предоставит Java IO.
Классы Java IO API
Базовые
Массивы
Files
Буферизация
Это самые распространяемые по использованию классы, но в нашей серии уроков мы на примерах рассмотрим все классы Java IO API.
ПОХОЖИЕ ПУБЛИКАЦИИ
-
None Found
5 комментариев к статье «Урок 1. Введение в Java IO»
Доброго времени суток. У вас очень полезный ресурс и канал на ютюбе, большое за это спасибо!
Хотел бы единственное сделать небольшое замечание, было бы очень удобно если бы у вас на сайте появились кнопки для перехода на предыдущую/следующею статьи. Все остальное очень круто. Спасибо.
