Перейти к основному содержимому

Простые способы записи Java InputStream в OutputStream

· 3 мин. чтения

Задача: Наибольшая подстрока без повторений

Для заданной строки s, найдите длину наибольшей подстроки без повторяющихся символов. Подстрока — это непрерывная непустая последовательность символов внутри строки...

ANDROMEDA 42

1. Обзор

В этом кратком руководстве мы узнаем, как записать поток ввода Java в поток вывода Java `` . Сначала мы будем использовать базовую функциональность из Java 8 и Java 9. Затем мы рассмотрим пару внешних библиотек — Guava и библиотеку ввода-вывода Apache Commons .

Служебные методы, предоставляемые Java 9, Guava и Apache Commons IO, не очищают и не закрывают потоки. Итак, нам нужно будет управлять этими ресурсами, используя блок try-with-resources или finally .

2. Использование Java 8

Во-первых, мы начнем с создания простого метода с использованием vanilla Java для копирования содержимого из InputStream в OutputStream :

void copy(InputStream source, OutputStream target) throws IOException {
byte[] buf = new byte[8192];
int length;
while ((length = source.read(buf)) > 0) {
target.write(buf, 0, length);
}
}

Этот код довольно прост — мы просто считываем несколько байтов, а затем записываем их.

3. Использование Java 9

Java 9 предоставляет вспомогательный метод InputStream.transferTo() для этой задачи .

Давайте посмотрим, как мы будем использовать метод transferTo() :

@Test
public void givenUsingJavaNine_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
String initialString = "Hello World!";

try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
inputStream.transferTo(targetStream);

assertEquals(initialString, new String(targetStream.toByteArray()));
}
}

Обратите внимание, что при работе с файловыми потоками более эффективно использовать Files.copy() , чем метод transferTo() .

4. Использование гуавы

Далее давайте посмотрим, как мы будем использовать вспомогательный метод Guava ByteStreams.copy() .

Нам нужно включить зависимость guava в наш pom.xml :

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>

Давайте создадим простой тестовый пример, чтобы показать, как мы можем использовать ByteStreams для копирования данных:

@Test
public void givenUsingGuava_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
String initialString = "Hello World!";

try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
ByteStreams.copy(inputStream, targetStream);

assertEquals(initialString, new String(targetStream.toByteArray()));
}
}

5. Использование Commons IO

Наконец, давайте посмотрим, как мы будем использовать метод Commons IO IOUtils.copy() для этой задачи.

Конечно, нам нужно добавить зависимость commons-io к pom.xml :

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>

Давайте создадим простой тестовый пример, используя IOUtils для копирования данных из входного потока в выходной поток:

@Test
public void givenUsingCommonsIO_whenCopyingInputStreamToOutputStream_thenCorrect() throws IOException {
String initialString = "Hello World!";

try (InputStream inputStream = new ByteArrayInputStream(initialString.getBytes());
ByteArrayOutputStream targetStream = new ByteArrayOutputStream()) {
IOUtils.copy(inputStream, targetStream);

assertEquals(initialString, new String(targetStream.toByteArray()));
}
}

Примечание: Commons IO предоставляет дополнительные методы для работы с InputStream s и OutputStream s. IOUtils.copyLarge() следует использовать всякий раз, когда необходимо скопировать 2 ГБ или более данных.

6. Заключение

В этой статье мы рассмотрели простые способы копирования данных из InputStream в OutputStream .

Реализация этих примеров доступна на GitHub .