1. Класс OutputStream
С потоками ввода мы только что разобрались. Настало время поговорить о потоках вывода.
Класс OutputStream
является классом-родителем для всех классов, которые поддерживают байтовый вывод. Это абстрактный класс, который сам ничего не делает: для этого у него есть классы-наследники на все случаи жизни.
Сложновато звучит. Если попроще, этот класс оперирует байтами, а не, например, символами или другими типами данных. А то, что он абстрактный, значит, что мы обычно используем не его, а один из его классов-наследников. Например, FileOutputStream
и ему подобные.
Но вернемся к классу OutputStream
. У этого класса есть методы, которые обязаны реализовывать все его классы-наследники. Вот основные из них:
Методы | Описание |
---|---|
|
Записывает один байт (не int ) в поток. |
|
Записывает массив байт в поток |
|
Записывает часть массива байт в поток |
|
Записывает в поток все данные, которые хранятся в буфере |
|
Закрывает поток |
При создании объекта класса-наследника InputStream
обычно указывается объект-источник, из которого InputStream
читает данные. При создании объекта класса-наследника OutputStream
также обычно указывается целевой объект или целевой поток, в который будут записываться данные.
Вкратце пройдемся по всем методам класса OutputStream
:
Метод write(int b)
Этот метод записывает в поток вывода один байт (не int
). Переданное значение приводится к типу байт, три первые байта отбрасываются.
Метод write(byte[] buffer)
Записывает в поток вывода переданный массив байтов. Все.
Метод write(byte[] buffer, int offset, int length)
Записывает в поток вывода часть переданного массива байтов. Переменная offset задает номер первого элемента массива, length
— длина записываемого фрагмента.
Метод flush()
Метод flush()
используется, чтобы принудительно записать в целевой поток данные, которые могут кэшироваться в текущем потоке. Актуально при использовании буферизации и/или нескольких объектах потоков, организованных в цепочку.
Метод close()
Записывает в целевой объект все незаписанные данные. Метод close()
можно не вызывать, если вы используете try
-with-resources.
Пример — копирование файла
Код | Примечание |
---|---|
|
InputStream для чтения из файлаOutputStream для записи в файлБуфер, в который мы будем считывать данные Пока данные есть в потоке Считываем данные в буфер Записываем данные из буфера во второй поток |
2. Класс Writer
Класс Writer
— это полный аналог класса OutputStream
, и снова только с одним отличием: он работает с символами, char
, вместо байт.
Это абстрактный класс: объекты класса Writer
создать нельзя. Его основная цель — быть единым классом-родителем для сотен классов-наследников и задать для них общие методы работы с символьными потоками.
Методы класса Writer
(и всех его классов-наследников):
Методы | Описание |
---|---|
|
Записывает один символ (не int ) в поток. |
|
Записывает массив символов в поток |
|
Записывает часть массива символов в поток |
|
Записывает строку в поток |
|
Записывает часть строки в поток |
|
Записывает в поток все данные, которые хранятся в буфере |
|
Закрывает поток |
Методы очень похожи на методы класса OutputStream
, только работают с символами вместо байт.
Краткое описание методов:
Метод write(int b)
Этот метод записывает в поток вывода один символ char
(не int
). Переданное значение приводится к типу char
, два первых байта отбрасываются.
Метод write(char[] buffer)
Записывает в поток вывода переданный массив символов.
Метод write(char[] buffer, int offset, int length)
Записывает в поток вывода часть переданного массива символов. Переменная offset
задает номер первого элемента массива, length
— длина записываемого фрагмента.
Метод write(String str)
Записывает в поток вывода переданную строку.
Метод write(String str, int offset, int length)
Записывает в поток вывода часть переданной строки: строку преобразуют в массив символов. Переменная offset
задает номер первого элемента массива, length
— длина записываемого фрагмента.
Метод flush()
Метод flush()
используется, чтобы принудительно записать в целевой поток данные, которые могут кэшироваться в текущем потоке. Актуально при использовании буферизации и/или нескольких объектах потоков, организованных в цепочку.
Метод close()
Записывает в целевой объект все незаписанные данные. Метод close()
можно не вызывать, если вы используете try
-with-resources.
Пример программы, которая копирует текстовый файл:
Код | Примечание |
---|---|
|
Reader для чтения из файлаWriter для записи в файлБуфер, в который будем считывать данные Пока данные есть в потоке Читаем данные в буфер Записываем данные из буфера во второй поток |
Класс StringWriter
Есть еще один интересный класс-наследник от класса Writer
— это StringWriter
. В нем находится изменяемая строка — объект StringBuffer
. И каждый раз, когда вы что-то «пишете» в объект StringWriter
, текст просто добавляется во внутренний буфер.
Пример:
Код | Примечание |
---|---|
|
Создается целевой символьный поток StringWriter Строка пишется в буфер внутри StringWriter Строка пишется в буфер внутри StringWriter Преобразовываем содержимое объекта к строке |
В данном случае класс StringWriter
— это, по сути, обертка над классом StringBuffer
, однако класс StringWriter
— это наследник класса-потока Writer
, и он может использоваться в цепочках из объектов-потоков. Довольно полезное свойство на практике.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
покаумолчали?