[], плюс два int-числа. Всі ці методи нічого не повертають (void). p align="justify"> Метод write (int) є абстрактним і повинен бути реалізований в класах-спадкоємців. Цей метод приймає як параметр int, але реально записує в потік тільки byte - молодші 8 біт у двійковому поданні. Інші 24 біта будуть проігноровані. У разі виникнення помилки цей метод кидає java.io.IOException, як, втім, і більшість методів, пов'язаних з введенням-висновком. p align="justify"> Для запису в потік відразу деякої кількості байт методом write () передається масив байт. Або, якщо ми хочемо записати тільки частина масиву, то передаємо масив byte [] і два int-числа - відступ і кількість байт для запису. Зрозуміло, що якщо вказати невірні параметри - наприклад, негативний відступ, негативне кількість байт для запису, або якщо сума відступ плюс довжина буде більше довжини масиву, - у всіх цих випадках кидається виняток IndexOutOfBoundsException. p align="justify"> Реалізація потоку може бути такою, що дані записуються не відразу, а зберігаються деякий час в пам'яті. Наприклад, ми хочемо записати у файл якісь дані, які отримуємо порціями по 10 байт, і так 200 разів поспіль. У такому випадку замість 200 звернень до файлу зручніше буде зібрати всі ці дані в пам'яті, а потім одним заходом записати всі 2000 байт. Тобто клас вихідного потоку може використовувати деякий внутрішній механізм для буферизації (тимчасового зберігання перед відправкою) даних. Щоб переконатися, що дані записані в потік, а не зберігаються в буфері, викликається метод flush (), визначений у OutputStream. У цьому класі його реалізація порожня, але якщо який-небудь із спадкоємців використовує буферизацію даних, то цей метод повинен бути в ньому перевизначений. p align="justify"> Коли робота з потоком закінчена, його слід закрити. Для цього викликається метод close (). Цей метод спочатку звільняє буфер (викликом методу flush), після чого потік закривається і звільняються всі пов'язані з ним системні ресурси. Закритий потік не може виконувати операції виведення і не може бути відкритий заново. У класі OutputStream реалізація методу close () не виробляє ніяких дій. p align="justify"> Отже, класи InputStream і OutputStream визначають необхідні методи для роботи з байтовими потоками даних. Ці класи є абстрактними. Їх завдання - визначити загальний інтерфейс для класів, які отримують дані з різних джерел. Такими джерелами можуть бути, наприклад, масив байт, файл, рядок і т.д. Всі вони, або, принаймні, найбільш поширені, будуть розглянуті далі. p align="justify"> Класи-реалізації потоків даних
Класи ByteArrayInputStream і ByteArrayOutputStream
Самий природний і простий джерело, звідки можна зчитувати байти, - це, звичайно, масив байт. Клас ByteArrayInputStream представляє потік, що зчитує дані з масиву байт. Цей клас має конструктор, якому як параметр передається масив byte []. Відповідно, при виклику методів read () повертаються дані будуть братися саме з цього масиву. Наприклад:
byte [] bytes = {1, -1,0}; in = ByteArrayInputStream (bytes); readedInt = in.read ();// readedInt = 1.out.println ("first element read is: "
+ readedInt); = in.read ();
// readedInt = 255. Однак
// (byte) readedInt дасть значення -1
System.out.println ("second element read is:"
+ readedInt); = in.read ();// readedInt = 0.out.println ("third element read is:"
+ readedInt);
Якщо запустити таку програму, на екрані відобразиться наступне:
first element read is: 1element read is: 255
third element read is: 0
При виклику методу read () дані зчитувалися з масиву bytes, переданого в конструктор ByteArrayInputStream. Зверніть увагу, в даному прикладі другу вважати значення дорівнює 255, а не -1, як можна було б очікувати. Щоб зрозуміти, чому це відбулося, потрібно згадати, що метод read зчитує byte, але повертає значення int, отримане додаванням необхідного числа нулів (у двійковому представленні). Байт, рівний -1, в двійковому поданні має вигляд 11111111 і, відповідно, число типу int, одержуване приставкою 24-х нулів, дорівнює 255 (в десяткового системі). Однак якщо явно привести його до byte, отримаємо початкове значення. p align="justify"> Аналогічно, для запису байт в масив застосовується клас ByteArrayOutputStream. Цей клас використовує всередині себе об'єкт byte [], куди записує дані, передані при виклику методів write (). Щоб отримати записані в масив дані, викликається метод toByteArray (). Приклад:
ByteArrayOutputStream out = ByteArrayOutputStream ();. write (10);. write (11); [] bytes = out.toByteArray ();
У цьому прикладі в результаті масив byte...