Буферизуемые потоки имеют хранящийся в памяти промежуточный буфер, из которого считываются выходные данные потока. Наличие такого буфера позволяет повысить производительность операций ввода-вывода, а также осуществлять дополнительные операции – устанавливать метки (маркеры) для какого-либо элемента, находящегося в буфере потока и даже делать возврат считанных элементов в поток (в пределах буфера).
Абстрактный класс InputStream (“входной поток”) инкапсулирует модель входных потоков, позволяющих считывать из них данные. Абстрактный класс OutputStream (“выходной поток”) - модель выходных потоков, позволяющих записывать в них данные. Абстрактные методы этих классов реализованы в классах-потомках.
Методы класса InputStream:
Метод | Что делает |
int available() | Текущее количество байт, доступных для чтения из потока. |
int read() | Читает один байт из потока и возвращает его значение в виде целого, лежащего в диапазоне от 0 до 255. При достижении конца потока возвращает -1. |
int read(byte[] b) int read(byte[] b, int offset, int count) | Пытается прочесть b.length байт из потока в массив b. Возвращает число реально прочитанных байт. После достижения конца потока последующие считывания возвращают -1. |
long skip(long count) | Попытка пропускать (игнорировать) count байт из потока. count ≤0, пропуска байт нет. Возвращается реально пропущенное число байт. Если это значение ≤0, пропуска байт не было. |
boolean markSupported() | Возвращает true в случае, когда поток поддерживает операции mark и reset, иначе – false. |
void mark(int limit) | Ставит метку в текущей позиции начала потока. Используется для последующего вызова метода reset, с помощью которого считанные после установки метки данные возвращаются обратно в поток. Эту операцию поддерживают не все потоки. См. метод markSupported. |
void reset() | Восстанавливает предшествующее состояние данных в начале потока, возвращая указатель начала потока на помеченный до того меткой элемент. То есть считанные после установки метки данные возвращаются обратно в поток. Попытка вызова при отсутствии метки или выходе её за пределы лимита приводит к возбуждению исключения IOException. Эту операцию поддерживают не все потоки. См. методы markSupported и mark. |
void close() | Закрытие потока. Последующие попытки чтения из этого потока приводят к возбуждению исключения IOException. |
Все методы класса InputStream, кроме markSupported и mark, возбуждают исключение IOException – оно возникает при ошибке чтения данных.
Методы класса OutputStream:
Метод | Что делает |
void write(int b) | Записывает один байт в поток. Благодаря использованию типа int можно использовать в качестве параметра целочисленное выражение без приведения его к типу byte. Напомним, что в выражениях “короткие” целые типы автоматически преобразуются к типу int. |
void write(byte[] b) void write(byte[] b, int offset, int count) | Записывает в поток массив байт. Если заданы параметры offset и count, записывается не весь массив, а count байт начиная с индекса offset. |
void flush() | Форсирует вывод данных из выходного буфера и его очистку. Необходимость этой операции связана с тем, что в большинстве случаев данные уходят “во внешний мир” на запись не каждый раз после вызова write, а только после заполнения выходного буфера. Таким образом, если операции записи разделены паузой (большим интервалом времени), и требуется, чтобы уход данных из выходного буфера совершался своевременно, после последнего вызова оператора write, предшествующего паузе, надо вызывать оператор flush. |
void close() | Закрытие потока. Последующие попытки записи в этот поток приводят к возбуждению исключения IOException. |
Все методы этого класса возбуждают IOException в случае ошибки записи.
Не все классы потоков являются потомками InputStream/OutputStream. Для чтения строк (в виде массива символов) используются потомки абстрактного класса java.io.Reader (“читатель”). В частности, для чтения из файла – класс FileReader. Аналогично, для записи строк используются классы- потомки абстрактного класса java.io.Writer (“писатель”). В частности, для записи массива символов в файл– класс FileWriter.
Имеется ещё один важный класс для работы с файлами, не входящий в иерархии InputStream/OutputStream и Reader/ Writer. Это класс RandomAccessFile (“файл с произвольным доступом”), предназначенный для чтения и записи данных в произвольном месте файла. Такой файл с точки зрения класса RandomAccessFile представляет массив байт, сохранённых на внешнем носителе. Класс RandomAccessFile не является абстрактным, поэтому можно создавать его экземпляры.
Все операции чтения и записи начинаются с позиции, задаваемой файловым указателем перед началом операции. После каждой такой операции файловый указатель сдвигается к концу файла на число позиций (байт), соответствующее типу считанных данных. В случае, когда во время записи файловый указатель выходит за конец файла, размер файла автоматически увеличивается.
Важнейшие методы класса RandomAccessFile:
Метод | Что делает |
Общие параметры файла | |
long getFilePointer() | Возвращает значение файлового указателя - текущую позицию в файле считывающей/записывающей головки. Индексация начинается с нуля и даётся в числе байт. |
long length() | Длина файла (в байтах). |
void setLength(long newLength) | Изменение длины файла – она устанавливается равной newLength. Если newLength меньше текущей длины, файл укорачивается путём отбрасывания его конца. При этом если файловый указатель находился в отбрасываемой части, он устанавливается в конец файла, иначе его позиция не меняется. Если newLength больше текущей длины, файл увеличивает размер путём добавления в конец нового пространства, содержимое которого не гарантируется. |
void close() | Закрытие потока. Последующие попытки доступа к этому потоку приводят к возбуждению исключения IOException. |
Побайтные операции установки позиции | |
void seek(long pos) | Установка файлового указателя в позицию pos. |
int skipBytes(int n) | Пропуск n байт – передвижение считывающей/записывающей головки на n байт. Если n>0, то вперёд, к концу файла. Если n≤0, то позиция головки не меняется. Возвращается число реально пропущенных байт. Оно может быть меньше n – например, из-за достижения конца файла. |
Побайтные операции чтения | |
int read() | Читает один байт из потока и возвращает его значение в виде целого, лежащего в диапазоне от 0 до 255. При достижении конца потока возвращает -1. |
int read(byte[] b) | Пытается прочесть b.length байт из потока в массив b. Возвращает число реально прочитанных байт. После достижения конца потока последующие считывания возвращают -1. |
int read(byte[] b, int offset, int count) | Пытается прочесть count байт из потока в массив b, записывая их начиная с позиции offset. Возвращает число реально прочитанных байт. После достижения конца потока последующие считывания возвращают -1. |
void readFully(byte[] b) | Считывает из файла b.length байт, начиная с текущей позиции файлового указателя, и заполняет весь буферный массив b. |
void readFully(byte[] b, int offset, int count) | Считывает из файла в массив count байт, записывая их начиная с байта, имеющего позицию offset. |
Побайтные операции записи | |
void write(int b) | Запись в файл одного байта b. То же, что writeByte(b). |
void write(byte[] b) | Запись в файл всего массива байт b, т.е. b.length байт. |
void write(byte[] b, int offset, int count) | Запись в файл count байт массива b начиная с байта массива, имеющего индекс offset. |
Чтение одиночных значений примитивного типа | |
boolean readBoolean() | Считывает значение boolean |
byte readByte() | Считывает значение byte |
short readShort() | Считывает значение short |
int readInt() | Считывает значение int |
long readLong() | Считывает значение long |
int readUnsignedByte() | Считывает значение типа “беззнаковый байт”( тип отсутствует в Java) и преобразует в значение типа int |
int readUnsignedShort() | Считывает значение типа “беззнаковое короткое целое”( тип отсутствует в Java) и преобразует в значение типа int |
char readChar() | Считывает значение char |
float readFloat() | Считывает значение float |
double readDouble() | Считывает значение double |
Запись одиночных значений примитивного типа | |
void writeBoolean(boolean v) | Запись в файл значение boolean |
void writeByte(int v) | Запись в файл значение byte. Благодаря использованию типа int можно использовать в качестве параметра целочисленное выражение без приведения его к типу byte. |
void writeShort(int v) | Запись в файл значение short. Благодаря использованию типа int можно использовать в качестве параметра целочисленное выражение без приведения его к типу short. |
void writeInt(int v) | Запись в файл значение int |
void writeLong(long v) | Запись в файл значение long |
void writeChar(int v) | Запись в файл значение char. Благодаря использованию типа int можно использовать в качестве параметра целочисленное выражение без приведения его к типу char. |
void writeFloat(float v) | Запись в файл значение float |
void writeDouble(double v) | Запись в файл значение double |
Чтение отдельных строк | |
String readLine() | Считывает из файла строку символов от текущей позиции файлового указателя до места переноса на новую строку (символ возврата каретки или последовательность “\n”) или конца файла. При этом старшие байты получившихся в строке символов UNICODE оказываются равными нулю, т.е. поддерживается только часть кодовой таблицы. Метод полезен для считывания текста, записанного в кодировке ANSI. |
String readUTF | Считывает из файла строку символов в кодировке UTF-8 от текущей позиции файлового указателя. Число последующих считываемых байт строки в кодировке UTF-8 задаётся первыми двумя считанными байтами. |
Запись отдельных строк | |
void writeBytes(String s) | Запись в файл строки s как последовательности байт, соответствующих символам строки. При этом каждому символу соответствует один записываемый байт, так как у каждого символа UNICODE отбрасывается старший из двух байт ( записывается младший байт). Используется для записи символов в кодировке ANSI. См. также метод writeChars, в котором записываются оба байта. |
void writeChars(String s) | Запись в файл строки s как последовательности байт, соответствующих символам строки. При этом каждому символу UNICODE соответствует два записываемых байта. |
void writeUTF(String s) | Запись в файл строки s как последовательности байт, соответствующих символам строки в кодировке UTF-8. |
Все методы класса RandomAccessFile, кроме getChannel(), возбуждают исключение IOException – оно возникает при ошибке записи или ошибке доступа к данным.