Потоки виведення, outputstream

Стандартна бібліотека Java має вельми розвинені засоби виведення даних. Всі можливості виведення даних зосереджені в пакеті java.io.

Існують дві паралельні ієрархії класів виведення. OutputStream і Writer. Клас Writer введений в останніх версіях Java.

У даній статті розглядається питання використання потоків для виведення даних в файл. Ієрархії вихідних OutputStream потоків представлена ​​на наступному малюнку.

Потоки виведення, outputstream

Потік Stream - це абстрактне значення джерела або приймача даних, які здатні обробляти інформацію. Є два типи потоків: байтові і символьні. У деяких ситуаціях символьні потоки більш ефективні, ніж байтові. Класи, похідні від класів OutputStream або Writer. мають методи з іменами write () для запису одиночних байтів або масиву байтів (відповідають за виведення даних).

Клас OutputStream - це абстрактний клас, що визначає байтовий потоковий виведення.

Спадкоємці даного класу визначають куди направляти дані: в масив байтів, в файл або канал. З масиву байт можна створити текстову рядок String.

Методи класу OutputStream:

  • void write (int b) записує один байт у вихідний потік. Аргумент цього методу має тип int, що дозволяє викликати write, передаючи йому вираз, при цьому не потрібно виконувати приведення його типу до byte.
  • void write (byte b []) записує у вихідний потік весь зазначений масив байтів.
  • void write (byte b [], int off, int len) записує в потік частина масиву len байтів, починаючи з елемента b [off].
  • void flush () очищає будь-які вихідні буфери, завершуючи операцію виведення.
  • void close () закриває вихідний потік. Наступні спроби записи в цей потік порушуватимуть IOException.

Клас ByteArrayOutputStream представляє потік виведення, який використовує масив байтів в якості місця виведення. Щоб створити об'єкт даного класу, можна використовувати один з його конструкторів:

Перший конструктор створює масив даних для зберігання байтів довжиною в 32 байта, а другий конструктор створює масив довжиною size.

Приклади використання класу ByteArrayOutputStream:

У класі ByteArrayOutputStream метод write записує в потік деякі дані (масив байтів). Цей масив байтів записується в об'єкті ByteArrayOutputStream в захищене поле buf, яке представляє також масив байтів (protected byte [] buf). Так як метод write може викликати виключення, то виклик цього методу поміщається в блок try..catch.

Використовуючи методи toString () і toByteArray (). можна отримати масив байтів buf у вигляді тексту або безпосередньо у вигляді масиву байт.

За допомогою методу writeTo можна перенаправити масив байт в інший потік. Даний метод в якості параметра приймає об'єкт OutputStream. в який проводиться запис масиву байт:

Для ByteArrayOutputStream не треба явно закривати потік за допомогою методу close.

Клас FileOutputStream створює об'єкт класу OutputStream, який можна використовувати для запису байтів в файл. Це основний клас для роботи з файлами. Створення нового об'єкта не залежить від того, чи існує заданий файл чи ні. Якщо файл відсутній, то буде створено новий файл. У разі спроби відкриття файлу, доступного тільки для читання, буде викликано виключення.

FileOutputStream має наступний конструктори:

Сенс конструкторів останнього зрозумілий з їх опису. Але є кілька нюансів:

  • При відкритті файлу на запис, якщо файл не існує, то він буде створений.
  • Якщо файл існує, то він буде повністю оновлений. Тобто якщо відкрити і відразу закрити файл, то вміст файлу буде знищено; реальний файл на диску стане нульової довжини.
  • Винятком для попереднього правила є останній з конструкторів. Якщо третьому параметру append привласнити значення true, то можна буде дописувати в кінець файлу.

Будь-якої додаткової функціональності в порівнянні з базовим класом FileOutputStream не додають.

Клас BufferedOutputStream створює буфер для потоків виведення. Цей буфер накопичує виводяться байти без постійного звернення до пристрою. І коли буфер заповнений, проводиться запис даних.

Клас BufferedOutputStream в конструкторі приймає як параметр об'єкт OutputStream - в прикладі це файловий потік виведення FileOutputStream.

BufferedOutputStream Не додає багато нових функцій, він просто оптимізує дію потоку виводаі його слід використовувати для організації більш ефективного буферизованного виведення в потік.

Клас DataOutputStream дозволяє писати дані в потік через інтерфейс DataOutput, який визначає методи, що перетворюють елементарні значення в форму послідовності байтів. Такі потоки полегшують збереження в файлі двійкових даних.

Для запису кожного з примітивних типів призначений свій метод класу DataOutputStream:

  • writeByte (int value) - записує в потік 1 байт
  • writeChar (int value) - записує 2х-байтовое значення char
  • writeInt (int value) - записує в потік цілочисельне значення int
  • writeShort (int v) - записує в потік значення short
  • writeFloat (float value) - записує в потік 4-байтовое значення float
  • writeDouble (double value) - записує в потік 8-байтовое значення double
  • writeBoolean (boolean value) - записує в потік Булевой однобайтовое значення
  • writeLong (long value) - записує в потік значення long
  • writeUTF (String value) - записує в потік рядок в кодуванні UTF-8

PrintStream є саме тим класом, який використовується для виведення інформації в консоль. Коли ми з допомогою виклику System.out.println () пишемо в консоль деяку інформацію, то тим самим використовується PrintStream, так як змінна out класу System являє об'єкт класу PrintStream, а метод println () - це метод класу PrintStream.

Але PrintStream можна використовувати для запису інформації в потік виводу. Наприклад, запишемо інформацію в файл:

В даному прикладі використовується конструктор PrintStream. який в якості параметра приймає потік виведення FileOutputStream. Можна було б також використовувати конструктор із зазначенням назви файлу для запису: PrintStream (String filename).

За допомогою методу println () проводиться запис інформації в вихідний потік - тобто в об'єкт FileOutputStream. У випадку з виведенням на консоль за допомогою System.out.println () в якості потоку виведення виступає консоль.

Для виведення інформації в вихідний потік PrintStream використовує такі методи:

Наступний код показує можливості використання форматованого виведення класу PrintStream:

Клас ObjectOutputStream використовується для сериализации об'єктів в потік. Серіалізация представляє процес запису стану об'єкта в потік, відповідно процес вилучення або відновлення стану об'єкта з потоку називається десеріалізацію. Серіалізация дуже зручна, коли йде робота зі складними об'єктами.

Для створення об'єкта ObjectOutputStream необхідно в конструктор передати потік, в який буде проводиться запис об'єктів.

Для запису даних ObjectOutputStream використовує ряд методів, серед яких можна виділити наступні: