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, и он может использоваться в цепочках из объектов-потоков. Довольно полезное свойство на практике.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
покаумолчали?