1. Обзор
В этой статье мы рассмотрим класс StreamUtils
и то, как мы можем его использовать.
Проще говоря, StreamUtils
— это класс Spring, который содержит некоторые служебные методы для работы с потоком — InputStream
и OutputStream
, которые находятся в пакете java.io
и не связаны с Stream API Java 8.
2. Зависимость от Maven
Класс StreamUtils
доступен в модуле spring-core, поэтому давайте добавим его в наш pom.xml
:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
Вы можете найти последнюю версию библиотеки в центральном репозитории Maven .
3. Копирование потоков
Класс StreamUtils
содержит несколько перегруженных методов с именем copy
()
, а также некоторые другие варианты:
диапазон копирования()
копировать массив байтов ()
копироватьстроку()
Мы можем копировать потоки без использования каких-либо библиотек. Однако код будет громоздким, и его будет гораздо труднее читать и понимать.
Обратите внимание, что мы опускаем закрытие потоков для простоты.
Давайте посмотрим, как мы можем скопировать содержимое InputStream
в заданный OutputStream
:
@Test
public void whenCopyInputStreamToOutputStream_thenCorrect() throws IOException {
String inputFileName = "src/test/resources/input.txt";
String outputFileName = "src/test/resources/output.txt";
File outputFile = new File(outputFileName);
InputStream in = new FileInputStream(inputFileName);
OutputStream out = new FileOutputStream(outputFile);
StreamUtils.copy(in, out);
assertTrue(outputFile.exists());
String inputFileContent = getStringFromInputStream(new FileInputStream(inputFileName));
String outputFileContent = getStringFromInputStream(new FileInputStream(outputFileName));
assertEquals(inputFileContent, outputFileContent);
}
Созданный файл содержит содержимое InputStream
.
Обратите внимание, что getStringFromInputStream()
— это метод, который принимает InputStream
и возвращает его содержимое в виде String
. Реализация метода доступна в полной версии кода.
Нам не нужно копировать все содержимое InputStream
, мы можем скопировать диапазон содержимого в заданный OutputStream,
используя метод copyRange()
:
@Test
public void whenCopyRangeOfInputStreamToOutputStream_thenCorrect() throws IOException {
String inputFileName = "src/test/resources/input.txt";
String outputFileName = "src/test/resources/output.txt";
File outputFile = new File(outputFileName);
InputStream in = new FileInputStream(inputFileName);
OutputStream out = new FileOutputStream(outputFileName);
StreamUtils.copyRange(in, out, 1, 10);
assertTrue(outputFile.exists());
String inputFileContent = getStringFromInputStream(new FileInputStream(inputFileName));
String outputFileContent = getStringFromInputStream(new FileInputStream(outputFileName));
assertEquals(inputFileContent.substring(1, 11), outputFileContent);
}
Как мы видим здесь, функция copyRange()
принимает четыре параметра: InputStream
, OutputStream
, позицию начала копирования и позицию окончания копирования. Но что, если указанный диапазон превышает длину InputStream
? Затем метод copyRange()
копирует до конца потока.
Давайте посмотрим, как мы можем скопировать содержимое String
в заданный OutputStream
:
@Test
public void whenCopyStringToOutputStream_thenCorrect() throws IOException {
String string = "Should be copied to OutputStream.";
String outputFileName = "src/test/resources/output.txt";
File outputFile = new File(outputFileName);
OutputStream out = new FileOutputStream("src/test/resources/output.txt");
StreamUtils.copy(string, StandardCharsets.UTF_8, out);
assertTrue(outputFile.exists());
String outputFileContent = getStringFromInputStream(new FileInputStream(outputFileName));
assertEquals(outputFileContent, string);
}
Метод copy()
принимает три параметра: копируемую строку , набор
символов
, который мы хотим использовать для записи в файл, и поток вывода
, в который мы хотим скопировать содержимое строки
.
Вот как мы можем скопировать содержимое данного InputStream
в новую строку
:
@Test
public void whenCopyInputStreamToString_thenCorrect() throws IOException {
String inputFileName = "src/test/resources/input.txt";
InputStream is = new FileInputStream(inputFileName);
String content = StreamUtils.copyToString(is, StandardCharsets.UTF_8);
String inputFileContent = getStringFromInputStream(new FileInputStream(inputFileName));
assertEquals(inputFileContent, content);
}
Мы также можем скопировать содержимое заданного массива байтов в OutputStream
:
public void whenCopyByteArrayToOutputStream_thenCorrect() throws IOException {
String outputFileName = "src/test/resources/output.txt";
String string = "Should be copied to OutputStream.";
byte[] byteArray = string.getBytes();
OutputStream out = new FileOutputStream("src/test/resources/output.txt");
StreamUtils.copy(byteArray, out);
String outputFileContent = getStringFromInputStream(new FileInputStream(outputFileName));
assertEquals(outputFileContent, string);
}
Или мы можем скопировать содержимое данного InputStream
в новый массив байтов:
public void whenCopyInputStreamToByteArray_thenCorrect() throws IOException {
String inputFileName = "src/test/resources/input.txt";
InputStream is = new FileInputStream(inputFileName);
byte[] out = StreamUtils.copyToByteArray(is);
String content = new String(out);
String inputFileContent = getStringFromInputStream(new FileInputStream(inputFileName));
assertEquals(inputFileContent, content);
}
4. Другая функциональность
InputStream можно передать в качестве аргумента методу стока
()
для удаления всех оставшихся данных в потоке:
StreamUtils.drain(in);
Мы также можем использовать метод emptyInput()
для получения эффективного пустого InputStream
:
public InputStream getInputStream() {
return StreamUtils.emptyInput();
}
Есть два перегруженных метода с именами nonClosing()
. InputStream
или OutputStream можно передать в качестве аргумента этим методам, чтобы получить вариант InputStream
или
OutputStream ,
который игнорирует вызовы метода close()
:
public InputStream getNonClosingInputStream() throws IOException {
InputStream in = new FileInputStream("src/test/resources/input.txt");
return StreamUtils.nonClosing(in);
}
5. Вывод
В этом кратком руководстве мы увидели, что такое StreamUtils
. Мы также рассмотрели все методы класса StreamUtils
и увидели, как их можно использовать.
Полную реализацию этого руководства можно найти на GitHub .