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 .