Класс OutputStream является базовым классом для всех классов, которые работают с бинарными потоками записи. Он объявляет три основных метода, необходимых для записи байтов данных в поток, а также имеет методы для закрытия и очистки потоков. Свою функциональность он реализует через следующие методы:
void close() - закрывает поток и освобождает все системные ресурсы, связанные с этим потоком. Закрытый поток не может выполнять операции вывода и не может быть открыт повторно. Возможна генерация исключений IOException;
void flush() - очищает буфер вывода, записывая все его содержимое. Многие операционные системы для повышения производительности буферизируют операции записи. Другими словами, вместо того, чтобы записывать каждый байт по мере его поступления, байты накапливаются в буфере размером от нескольких байтов до нескольких тысяч байтов. Затем, когда буфер заполняется, все данные записываются сразу. Метод flush() принудительно записывает данные независимо от того, заполнен буфер или нет;
abstract void write(int b) - записывает в выходной поток один байт, который представлен целочисленным параметром b, метод должен быть определен в дочерних классах. Выбрасывает исключение IOException, если произошла ошибка ввода-вывода, в частности, если выходной поток был закрыт;
int offset,
int length) -
записывает в выходной поток некоторое число байтов, равное length, из массива buffer, начиная со смещения offset, то есть с элемента buffer[offset]. Возможна генерация исключений IOException, NullPointerException, IndexOutOfBoundsException.
Абстрактные классы Reader и Writer
Платформа Java хранит значения символов, используя соглашения Unicode. Ввод-вывод потока символов автоматически преобразует этот внутренний формат в локальный набор символов и обратно. В англоязычных регионах локальный набор символов обычно представляет собой 8-битный расширенный набор символов ASCII. Таким образом, программа, которая использует потоки символов вместо потоков байтов, автоматически адаптируется к локальному набору символов.
Для обработки символьных потоков в формате Unicode применяется отдельная иерархия подклассов абстрактных классов Reader и Writer, которые почти полностью повторяют функциональность байтовых потоков, но являются более актуальными при передаче текстовой информации.
Абстрактный класс Reader предоставляет функционал для чтения текстовой информации. Рассмотрим его основные методы:
absract void close() - закрывает поток ввода и освобождает все связанные с ним системные ресурсы;
int read() - возвращает целочисленное представление следующего символа в потоке. Если таких символов нет, и достигнут конец файла, то возвращается число -1. Возможна генерация исключения IOException;
int read(char[] buffer) - считывает в массив buffer из потока символы, количество которых меньше либо равно длине массива buffer. Возвращает количество успешно считанных символов. При достижении конца файла возвращает
-1. Возможна генерация исключения IOException;
int read(CharBuffer buffer) - считывает в объект CharBuffer из потока символы. Возвращает количество успешно считанных символов. При достижении конца файла возвращает -1 Возможна генерация исключения IOException;
absract int read(char[] buffer,
int offset,
int count) -
считывает в массив buffer, начиная со смещения offset, из потока символы, количество которых равно count Возможна генерация исключений IOException и IndexOutOfBoundsException;
long skip(long count) - пропускает количество символов, равное count. Возвращает число успешно пропущенных символов. Если поток уже исчерпан до вызова этого метода, символы не пропускаются и возвращается ноль. Возможна генерация исключений IllegalArgumentException, если count отрицательно и IOException, если возникает ошибка ввода/вывода.
Единственные методы, которые должен реализовать подкласс класса Reader, это read(char[], int, int) и close(). Однако большинство подклассов переопределяют некоторые и некоторые другие методы, чтобы обеспечить более высокую эффективность и/или дополнительную функциональность.
Класс Writer определяет функционал для всех символьных потоков вывода. Его основные методы:
Writer append(char c) - добавляет в конец выходного потока символ c. Возвращает объект Writer. Возможна генерация исключений IOException;
Writer append(CharSequence chars) - добавляет в конец выходного потока набор символов chars. Возвращает объект Writer. Возможна генерация исключений IOException;
abstract void close() - закрывает поток, предварительно очищая его. Как только поток будет закрыт,
дальнейшие вызовы write() или flush() приведут к возникновению исключения IOException. Повторное закрытие ранее уже закрытого потока не имеет никакого эффекта;
abstract void flush() - очищает буферы потока Если поток сохранил какие-либо символы из различных методов write() в буфере, немедленно запишет их в предполагаемое место назначения. Если предполагаемым местом назначения является абстракция, предоставляемая базовой операционной системой, например файл, то очистка потока гарантирует только то, что байты, ранее записанные в поток, передаются операционной системе для записи, но не гарантирует, что они действительно записываются на физическое устройство, такое как дисковод;
void write(int c) - записывает в поток один символ, который имеет целочисленное представление. Возможна генерация исключений IOException;
int off,
int len) -
записывает в поток только несколько символов из массива buffer. Причем количество символов равно len, а отбор символов из массива начинается с индекса off Возможна генерация исключений IOException и IndexOutOfBoundsException;
void write(String str, int off, int len) - записывает в поток из строки некоторое количество символов, которое равно len, причем отбор символов из строки начинается с индекса off Возможна генерация исключений IOException и IndexOutOfBoundsException.
Методы, которые обязан реализовать подкласс класса Writer, это write(char[], int, int), flush() и close(). Однако большинство подклассов переопределяют и другие методы, чтобы обеспечить более высокую эффективность и/или дополнительную функциональность.
Функционал, описанный классами Reader и Writer, наследуется непосредственно классами символьных потоков, в частности классами
FileReader и FileWriter соответственно, предназначенными для работы с текстовыми файлами.