— Привіт, Аміго! Сьогодні ми знову будемо займатися розбором роботи 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).
— Тепер зрозуміло, як це все працює. Дякую, Еллі.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ