Java, як і багато сучасні мови програмування, що підтримує реалізацію потоків введення даних. В Java InputStream є базовим класом для байтових потоків. Даний клас є абстрактним, тобто у процесі роботи програми ми не можемо створювати його примірник. Однак у пакеті io є безліч класів, які успадковують і розширюють функціональність InputStream. Щоб використовувати цей клас в своєму коді, його потрібно імпортувати з пакету java.io.InputStream. Далі ми розглянемо базову функціональність, яку надає клас InputStream, а також основні класи, що реалізують його.
Методи класу InputStream
Перш ніж приступити до докладного вивчення методів класу InputStream, слід згадати, що він реалізує інтерфейси Closeable і AutoCloseable. Інтерфейс Closeable говорить нам про те, що при завершенні роботи з потоком його необхідно обов'язково закрити. Робиться це за допомогою методу close(). Оскільки більшість методів класу InputStream у разі виникнення помилки генерує виняток типу IOException, всі операції потрібно проводити в блоці try, а метод close() виносити в блок finally, щоб він спрацював незалежно від результату роботи в тілі try. Інтерфейс AutoCloseable значно скорочує обсяг технічного коду, оскільки дозволяє методу close() спрацьовувати автоматично і не додавати в ваш код блок finally. Якщо ви використовуєте сьому або пізнішу версію Java, InputStream можна поміщати в так званий try з ресурсами, що всі операції по закриттю потоків бере на себе.
Розглянемо основні методи класу InputStream: int available() – повертає доступне для читання кількість байтів; int read() – бере із ресурсу поточний байт і повертає його в цілочисельному поданні; якщо всі байти прочитані, повертає -1; int read(byte[]буфер) – читає доступні байти в зазначений буфер у вигляді масиву типу byte (кількість читаних байтів одно заданого розміру буфера; повертає кількість байтів, які вдалося прочитати; якщо всі доступні байти прочитані, повертає -1); int read(byte[]буфер, int зсув, int кількість байтів) – перевантаження попереднього методу, робить те ж саме, але з вказаною в «усунення» позиції і читає стільки, скільки вказано в «кількості байтів»; long skip(long кількість байтів) – пропускає вказану кількість байтів і повертає фактична кількість пропущених. InputStream реалізується декількома класами, призначеними для роботи з різними джерелами і типами даних. Нижче представлено дерево спадкування.
Читання файлів
Байтовий потік для читання інформації з файлів реалізується класом FileInputStream. Для того щоб відкрити файл для читання байтів, достатньо створити екземпляр даного класу, передавши його конструктору ім'я файла як аргумент. Якщо файлу з переданим ім'ям не існує, буде згенеровано виняток типу FileNotFoundException. У разі вдалого відкриття файлу, робота з ним виконується за допомогою описаних вище методів, так як FileInputStream є спадкоємцем InputStream.
Читання примітивних типів даних
У попередньому прикладі описувалася робота з байтовими значеннями, які можна інтерпретувати як символи. Але як бути, якщо нам необхідно прочитати ціле, дробове або логічне значення? Для цього в Java InputStream побічно розширюється класом DataInputStream. Даний клас є оболонкою для InputStream, який передається йому при створенні в якості аргументу конструктора. Такого роду потік читає дані в бінарному вигляді.
DataInputStream також реалізує інтерфейс DataInput і його методи для читання примітивних типів даних. Нижче представлений список цих методів.
Назви методів говорять самі за себе – кожен з них призначений для читання певного типу даних.
Буферізірованний потік вводу
Буферізірованний потік читання даних реалізується класом BufferedInputStream в Java. InputStream полягає в оболонку цим класом. Даний клас доповнює потік буфером, що дозволяє читати одночасно не один, а кілька байтів. Це дає можливість значно підвищити продуктивність операції. BufferedInputStream є прямим нащадком InputStream і, відповідно, успадковує всі зазначені вище методи. Цей клас має два конструктора: BufferedInputStream(InputStream потік вводу); BufferedInputStream(InputStream потік вводу, int розмір буфера) З сигнатури конструкторів можна зрозуміти, що перший встановлює розмір буфера за замовчуванням, а в другому є можливість задати їх вручну.
Висновок
Ми розглянули основні реалізації InputStream. Якщо вам потрібно перетворити отримані байти в рядок, то в Java InputStream to String(), на жаль, не перевантажений, тому для цього доведеться використовувати спеціальні утиліти, наприклад IOUtils з бібліотеки Apache Commons.