Что такое inputstream и outputstream

Потоки ввода-вывода. Работа с файлами

Потоки ввода-вывода

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

В основе всех классов, управляющих потоками байтов, находятся два абстрактных класса: InputStream (представляющий потоки ввода) и OutputStream (представляющий потоки вывода)

Но поскольку работать с байтами не очень удобно, то для работы с потоками символов были добавлены абстрактные классы Reader (для чтения потоков символов) и Writer (для записи потоков символов).

Все остальные классы, работающие с потоками, являются наследниками этих абстрактных классов. Основные классы потоков:

Что такое inputstream и outputstream. Смотреть фото Что такое inputstream и outputstream. Смотреть картинку Что такое inputstream и outputstream. Картинка про Что такое inputstream и outputstream. Фото Что такое inputstream и outputstream

Потоки байтов

Класс InputStream

Класс InputStream является базовым для всех классов, управляющих байтовыми потоками ввода. Рассмотрим его основные методы:

int available() : возвращает количество байтов, доступных для чтения в потоке

void close() : закрывает поток

long skip(long number) : пропускает в потоке при чтении некоторое количество байт, которое равно number

Класс OutputStream

Класс OutputStream является базовым классом для всех классов, которые работают с бинарными потоками записи. Свою функциональность он реализует через следующие методы:

void close() : закрывает поток

void flush() : очищает буфер вывода, записывая все его содержимое

void write(int b) : записывает в выходной поток один байт, который представлен целочисленным параметром b

void write(byte[] buffer) : записывает в выходной поток массив байтов buffer.

Абстрактные классы Reader и Writer

Абстрактный класс Reader предоставляет функционал для чтения текстовой информации. Рассмотрим его основные методы:

absract void close() : закрывает поток ввода

absract int read(char[] buffer, int offset, int count) : считывает в массив buffer, начиная со смещения offset, из потока символы, количество которых равно count

long skip(long count) : пропускает количество символов, равное count. Возвращает число успешно пропущенных символов

Класс Writer определяет функционал для всех символьных потоков вывода. Его основные методы:

Writer append(char c) : добавляет в конец выходного потока символ c. Возвращает объект Writer

Writer append(CharSequence chars) : добавляет в конец выходного потока набор символов chars. Возвращает объект Writer

abstract void close() : закрывает поток

abstract void flush() : очищает буферы потока

void write(int c) : записывает в поток один символ, который имеет целочисленное представление

void write(char[] buffer) : записывает в поток массив символов

absract void write(char[] buffer, int off, int len) : записывает в поток только несколько символов из массива buffer. Причем количество символов равно len, а отбор символов из массива начинается с индекса off

void write(String str) : записывает в поток строку

void write(String str, int off, int len) : записывает в поток из строки некоторое количество символов, которое равно len, причем отбор символов из строки начинается с индекса off

Функционал, описанный классами Reader и Writer, наследуется непосредственно классами символьных потоков, в частности классами FileReader и FileWriter соответственно, предназначенными для работы с текстовыми файлами.

Теперь рассмотрим конкретные классы потоков.

Источник

Пакет java.io

Система ввода/вывода. Потоки данных (stream)

В Java для описания работы по вводу/выводу используется специальное понятие поток данных ( stream ). Поток данных связан с некоторым источником или приемником данных, способным получать или предоставлять информацию. Соответственно, потоки делятся на входящие – читающие данные и выходящие – передающие (записывающие) данные. Введение концепции stream позволяет отделить основную логику программы, обменивающейся информацией с любыми устройствами одинаковым образом, от низкоуровневых операций с такими устройствами ввода/вывода.

Что такое inputstream и outputstream. Смотреть фото Что такое inputstream и outputstream. Смотреть картинку Что такое inputstream и outputstream. Картинка про Что такое inputstream и outputstream. Фото Что такое inputstream и outputstream

Классы InputStream и OutputStream

Метод read() – это абстрактный метод, но именно с соблюдением всех указанных условий он должен быть реализован в классах-наследниках.

Точно так же, как InputStream – это базовый класс для потоков ввода, класс OutputStream – это базовый класс для потоков вывода.

Классы-реализации потоков данных

Классы ByteArrayInputStream и ByteArrayOutputStream

Если запустить такую программу, на экране отобразится следующее:

Классы FileInputStream и FileOutputStream

Результатом работы программы будет:

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

В приведенном примере для наглядности закрытие потоков производилось сразу же после окончания их использования в основном блоке. Однако лучше закрывать потоки в finally блоке.

Такой подход гарантирует, что поток будет закрыт и будут освобождены все связанные с ним системные ресурсы.

PipedInputStream и PipedOutputStream

Использование связки PipedInputStream и PipedOutputStream показано в следующем примере:

StringBufferInputStream
SequenceInputStream

Источник

Потоки для ввода данных

1. Потоки данных

Любая программа редко существует сама по себе. Обычно она как-то взаимодействует с «внешним миром». Это может быть считывание данных с клавиатуры, отправка сообщений, загрузка страниц из интернета или, наоборот, загрузка файлов на удалённый сервер.

Все эти вещи мы можем назвать одним словом — процесс обмена данными между программой и внешним миром. Хотя это уже не одно слово.

Сам процесс обмена данными можно разделить на два типа: получение данных и отправка данных. Например, вы считываете данные с клавиатуры с помощью объекта Scanner — это получение данных. И выводите данные на экран с помощью команды System.out.println() — это отправка данных.

Для описания процесса обмена данными в программировании используется термин поток. Откуда вообще взялось такое название?

В реальной жизни им может быть поток воды или поток людей (людской поток). В программировании же под потоком подразумевают поток данных.

Потоки — это универсальный инструмент. Они позволяют программе получать данные откуда угодно (входящие потоки) и отправляют данные куда угодно (исходящие потоки). Делятся на два вида:

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

Что же это за данные и в каком виде их можно читать? Другими словами, какие типы данных поддерживаются этими классами?

Особенность потоков в том, что данные из них можно читать (писать) только последовательно. Вы не можете прочитать данные из середины потока, не прочитав все данные перед ними.

Именно так работает чтение с клавиатуры через класс Scanner : вы читаете данные с клавиатуры последовательно: строка за строкой. Прочитали строку, прочитали следующую строку, прочитали следующую строку и т.д. Поэтому метод чтения строки и называется nextLine() (дословно — «следующая срока»).

Запись данных в поток OutputStream тоже происходит последовательно. Хороший пример — вывод на экран. Вы выводите строку, за ней еще одну и еще одну. Это последовательный вывод. Вы не можете вывести 1-ю строку, затем 10-ю, а затем вторую. Все данные записываются в поток вывода только последовательно.

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

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

Если сравнить эти четыре класса, мы получим такую картину:

Байты (byte)Символы (char)
Чтение данных
Запись данных

Практическое применение

2. Класс InputStream

Класс InputStream интересен тем, что является классом-родителем для сотен классов-наследников. В нем самом нет никаких данных, однако у него есть методы, которые есть у всех его классов-наследников.

Объекты-потоки вообще редко хранят в себе данные. Поток — это инструмент чтения/записи данных, но не хранения. Хотя бывают и исключения.

Методы класса InputStream и всех его классов-наследников:

МетодыОписание
Читает один байт из потока
Читает массив байт из потока
Читает все байты из потока
Пропускает n байт в потоке (читает и выкидывает)
Проверяет, сколько байт еще осталось в потоке
Закрывает поток

Вкратце пройдемся по этим методам:

Метод read()

Метод read(byte[] buffer)

Метод readAllBytes()

Метод skip(long n)

Возвращает число байт, которые были реально пропущены (если поток закончился раньше, чем прокрутили n байт).

Метод int available()

Метод возвращает количество байт, которое еще осталось в потоке

Метод void close()

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

InputStream для чтения из файла
OutputStream для записи в файл

Буфер, в который будем считывать данные
Пока данные есть в потоке

Считываем данные в буфер
Записываем данные из буфера во второй поток

В этом примере мы использовали два класса: FileInputStream — наследник InputStream для чтения данных из файла, и класс FileOutputStream — наследник OutputStream для записи данных в файл. О втором классе расскажем немного позднее.

Источник

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

1. Класс InputStream

Класс InputStream – это абстрактный класс. Все байтовые потоки чтения наследуются от класса InputStream.

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

Существует 3 основных read() метода:

Методы read() будут блокированы, пока доступные данные не будут прочитаны.

2. Класс OutputStream

Все байтовые потоки записи наследуются от абстрактного класса OutputStream.

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

Существуют 3 основных write() метода:

3. Класс FileInputStream

Поток FileInputStream используется в Java для чтения данных из файла.

Конструкторы класса FileInputStream:

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

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

4. Класс FileOutputStream

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

Конструкторы класса FileOutputStream:

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

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

Источник

Собеседование по Java — потоки ввода/вывода (вопросы и ответы)

Вопросы и ответы для собеседования Java по теме — потоки ввода/вывода.

К списку вопросов по всем темам

Вопросы

1. Какие существуют виды потоков ввода/вывода?
2. Назовите основные предки потоков ввода/вывода.
3. Что общего и чем отличаются следующие потоки: InputStream, OutputStream, Reader, Writer?
4. Что вы знаете о RandomAccessFile?
5. Какие есть режимы доступа к файлу?
6. В каких пакетах лежат классы-потоки?
7. Что вы знаете о классах-надстройках?
8. Какой класс-надстройка позволяет читать данные из входного байтового потока в формате примитивных типов данных?
9. Какой класс-надстройка позволяет ускорить чтение/запись за счет использования буфера?
10. Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?
11. Какой класс предназначен для работы с элементами файловой системы (ЭФС)?
12. Какой символ является разделителем при указании пути к ЭФС?
13. Как выбрать все ЭФС определенного каталога по критерию (например, с определенным расширением)?
14. Что вы знаете об интерфейсе FilenameFilter?
15. Что такое сериализация?
16. Какие условия “благополучной” сериализации объекта?
17. Какие классы позволяют архивировать объекты?

Ответы

1. Какие существуют виды потоков ввода/вывода?

Разделяют два вида потоков ввода/вывода: байтовые и символьные.

Что такое inputstream и outputstream. Смотреть фото Что такое inputstream и outputstream. Смотреть картинку Что такое inputstream и outputstream. Картинка про Что такое inputstream и outputstream. Фото Что такое inputstream и outputstream

Система ввода/вывода: http://developer.alexanderklimov.ru/android/java/io.php
Oracle Lesson: Basic I/O tutorial: https://docs.oracle.com/javase/tutorial/essential/io/

2. Назовите основные предки потоков ввода/вывода.

Байтовые: java.io.InputStream, java.io.OutputStream;

Символьные: java.io.Reader, java.io.Writer;

3. Что общего и чем отличаются следующие потоки: InputStream, OutputStream, Reader, Writer?

Базовый класс InputStream представляет классы, которые получают данные из различных источников:
— массив байтов
— строка (String)
— файл
— канал (pipe): данные помещаются с одного конца и извлекаются с другого
— последовательность различных потоков, которые можно объединить в одном потоке
— другие источники (например, подключение к интернету)

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

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

4. Что вы знаете о RandomAccessFile?

Класс RandomAccessFile наследуется напрямую от Object и не наследуется от вышеприведенных базовых классов ввода\вывода. Предназначен для работы с файлами, поддерживая произвольный доступ к их содержимому.

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

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

5. Какие есть режимы доступа к файлу?

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

6. В каких пакетах лежат классы-потоки?

Классы потоков ввода\вывода лежат в java.io; С JDK 7 добавлен более современный способ работы с потоками — Java NIO. Классы лежат в java.nio. Для работы с архивами используются классы из пакета java.util.

7. Что вы знаете о классах-надстройках?

8. Какой класс-надстройка позволяет читать данные из входного байтового потока в формате примитивных типов данных?

Для чтения байтовых данных (не строк) применяется класс DataInputStream. В этом случае необходимо использовать классы из группы InputStream.

Для преобразования строки в массив байтов, пригодный для помещения в поток ByteArrayInputStream, в классе String предусмотрен метод getBytes(). Полученный ByteArrayInputStream представляет собой поток InputStream, подходящий для передачи DataInputStream.

При побайтовом чтении символов из форматированного потока DataInputStream методом readByte() любое полученное значение будет считаться действительным, поэтому возвращаемое значение неприменимо для идентификации конца потока. Вместо этого можно использовать метод available(), который сообщает, сколько еще осталось символов.

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

Конструктор: DataInputStream(InputStream stream)
Методы: readDouble(), readBoolean(), readInt()

9. Какой класс-надстройка позволяет ускорить чтение/запись за счет использования буфера?

Для этого используются классы, позволяющие буферизировать поток:
java.io.BufferedInputStream(InputStream in) || BufferedInputStream(InputStream in, int size),
java.io.BufferedOutputStream(OutputStream out) || BufferedOutputStream(OutputStream out, int size),
java.io.BufferedReader(Reader r) || BufferedReader(Reader in, int sz),
java.io.BufferedWriter(Writer out) || BufferedWriter(Writer out, int sz)

10. Какие классы позволяют преобразовать байтовые потоки в символьные и обратно?

OutputStreamWriter — мост между классом OutputStream и классом Writer. Символы, записанные в поток, преобразовываются в байты.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *