Закриття потоків. Класи ByteArrayInputStream та ByteArrayOutputStream
Закриття потоків є важливим етапом при роботі з введенням-виведенням у Java, оскільки воно забезпечує звільнення ресурсів, що використовуються потоком, таких як дескриптори файлів. Якщо потоки не закривати, це може призвести до витоку ресурсів і вичерпання системних обмежень на відкриті файли або мережеві з’єднання.
Закриття потоків
У Java для закриття потоку використовується метод close(), який реалізовано в інтерфейсі Closeable (успадковується класами потоків). Починаючи з Java 7, з’явилася зручна конструкція try-with-resources, яка автоматично закриває потік після завершення роботи або після того, як було викинуто виняток.
Приклад використання try-with-resources:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream(“input.txt”);
FileOutputStream fos = new FileOutputStream(“output.txt”)) {
int byteData;
while ((byteData = fis.read()) != -1) {
fos.write(byteData);
}
} catch (IOException e) {
e.printStackTrace();
}
// Потоки автоматично закриваються після завершення блоку try
}
}
У цьому прикладі, навіть якщо виникає виняток, потоки fis і fos автоматично закриються завдяки конструкції try-with-resources.
Класи ByteArrayInputStream і ByteArrayOutputStream
Ці класи використовуються для роботи з байтовими масивами замість файлів чи інших зовнішніх джерел/потоків даних.
1. ByteArrayInputStream
ByteArrayInputStream дозволяє читати байти з масиву як із потоку. Це корисно, коли потрібно працювати з даними, що вже зберігаються в пам’яті, як із звичайного потоку.
Основні методи:
- int read() — читає наступний байт з потоку.
- int read(byte[] b, int off, int len) — читає до len байтів у масив b, починаючи з позиції off.
- void reset() — скидає внутрішній вказівник на початок потоку.
Приклад використання ByteArrayInputStream:
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
byte[] data = “Hello, World!”.getBytes();
try (ByteArrayInputStream bais = new ByteArrayInputStream(data)) {
int byteData;
while ((byteData = bais.read()) != -1) {
System.out.print((char) byteData); // Виводимо символи
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. ByteArrayOutputStream
ByteArrayOutputStream дозволяє записувати байти у внутрішній буфер, а потім отримати ці дані як масив байтів або рядок. Це зручно для створення тимчасових буферів даних у пам’яті.
Основні методи:
- void write(int b) — записує один байт.
- void write(byte[] b, int off, int len) — записує масив байтів.
- byte[] toByteArray() — повертає масив байтів, записаних у потік.
- String toString() — повертає записані байти у вигляді рядка.
Приклад використання ByteArrayOutputStream:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
String message = “Hello, ByteArrayOutputStream!”;
baos.write(message.getBytes());
// Отримуємо записані дані у вигляді масиву байтів
byte[] byteArray = baos.toByteArray();
System.out.println(new String(byteArray)); // Виводимо дані у вигляді рядка
} catch (IOException e) {
e.printStackTrace();
}
}
}
Основні моменти:
- ByteArrayInputStream читає дані з масиву байтів.
- ByteArrayOutputStream записує дані у внутрішній масив байтів.
- Ці класи часто використовуються для тимчасового зберігання даних у пам’яті перед їх подальшою обробкою або передачею.
Закриття потоківКласи ByteArrayInputStream та ByteArrayOutputStream