— Привет, Амиго! Сегодня мы снова будем заниматься разбором работы InputStream и OutputStream. На самом деле, то первое объяснение было немного упрощенным. Это не интерфейсы, а абстрактные классы, и они даже имеют по паре реализованных методов. Давай посмотрим, какие методы у них есть:
Методы класса InputStream | Что метод делает |
---|---|
|
— метод сразу читает блок байт в буфер (массив байт), пока буфер не заполнится или не закончатся байты там, откуда он их читает. Метод возвращает количество реально прочитанных байт (оно может быть меньше длины массива) |
|
— метод читает один байт и возвращает его как результат. Результат расширяется до int, для красоты. Если все байты уже прочитаны, метод вернет «-1». |
|
— метод возвращает количество непрочитанных (доступных) байт. |
|
— метод «закрывает» поток – вызывается после окончания работы с потоком. Объект выполняет служебные операции, связанные с закрытием файла на диске и т.д. Из потока больше нельзя читать данные. |
— Т.е. мы можем читать не только по одному байту, а и целыми блоками?
— Да.
— А записывать целыми блоками тоже можно?
— Да, вот смотри:
Методы OutputStream | Что метод делает |
---|---|
|
— метод записывает один байт информации. Тип int сужается до byte, лишняя часть просто отбрасывается. |
|
— метод записывает блок байт. |
|
— метод записывает часть блока байт. Используется в случаях, когда есть вероятность, что блок данных был заполнен не целиком |
|
— если есть данные, которые хранятся где-то внутри и еще не записаны, то они записываются. |
|
— метод «закрывает» поток – вызывается после окончания работы с потоком. Объект выполняет служебные операции, связанные с закрытием файла на диске и т.д.В поток больше нельзя писать данные, flush при этом вызывается автоматически. |
— А как будет выглядеть код копирования файла, если мы будем читать не по одному байту, а целыми блоками?
— Гм. Примерно так:
public static void main(String[] args) throws Exception
{
//Создаем поток-чтения-байт-из-файла
FileInputStream inputStream = new FileInputStream("c:/data.txt");
// Создаем поток-записи-байт-в-файл
FileOutputStream outputStream = new FileOutputStream("c:/result.txt");
byte[] buffer = new byte[1000];
while (inputStream.available() > 0) //пока есть еще непрочитанные байты
{
// прочитать очередной блок байт в переменную buffer и реальное количество в count
int count = inputStream.read(buffer);
outputStream.write(buffer, 0, count); //записать блок(часть блока) во второй поток
}
inputStream.close(); //закрываем оба потока. Они больше не нужны.
outputStream.close();
}
— С буфером все понятно, а что это за переменная count?
— Когда мы читаем самый последний блок данных в файле, может оказаться, что байт осталось не 1000, а, скажем, 328. Тогда и при записи нужно указать, что записать не весь блок, а только его первые 328 байт.
Метод read при чтении последнего блока вернет значение равное количеству реально прочитанных байт. Для всех чтений – 1000, а для последнего блока – 328.
Поэтому при записи блока мы указываем, что нужно записать не все байты из буфера, а только 328 (т.е. значение, хранимое в переменной count).
— Теперь понятно, как все это работает. Спасибо, Элли.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ