1. Обзор
В этой статье мы рассмотрим класс StreamUtils и то, как мы можем его использовать.
Проще говоря, StreamUtils – это класс Spring, который содержит некоторые служебные методы для работы с потоком – InputStream и OutputStream , которые находятся в пакете java.io и не связан с потоковым API Java 8.
2. Зависимость Maven
Класс StreamUtils доступен в модуле spring-core, поэтому давайте добавим его в ваш pom.xml :
org.springframework spring-core 5.2.8.RELEASE
Вы можете найти последнюю версию библиотеки в Центральном репозитории Maven .
3. Копирование потоков
Класс StreamUtils содержит несколько перегруженных методов с именем copy () , а также некоторые другие варианты:
- диапазон копирования()
- copyToByteArray()
- copyString()
Мы можем копировать потоки без использования каких-либо библиотек. Тем не менее, код будет громоздким и гораздо труднее читать и понимать.
Обратите внимание, что мы опускаем закрытие потоков для простоты.
Давайте посмотрим, как мы можем скопировать содержимое 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 и возвращает его содержимое в виде Строки . Реализация метода доступна в полной версии кода.
Нам не нужно копировать все содержимое 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); }
Как мы видим здесь, copy Range() принимает четыре параметра: InputStream , Inputstream , позицию для начала копирования и позицию для завершения копирования. Но что делать, если указанный диапазон превышает длину входного потока ? Метод copyRange() затем копирует до конца потока.
Давайте посмотрим, как мы можем скопировать содержимое Строки в заданный Выходной поток :
@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() принимает три параметра – копируемую строку , кодировку , которую мы хотим использовать для записи в файл, и поток OutputStream , в который мы хотим скопировать содержимое строки .
Вот как мы можем скопировать содержимое данного 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 может быть передан в качестве аргумента методу drain() для удаления всех оставшихся данных в потоке:
StreamUtils.drain(in);
Мы также можем использовать метод empty Input() для получения эффективного пустого Входной поток :
public InputStream getInputStream() { return StreamUtils.emptyInput(); }
Существует два перегруженных метода с именем non Closing() . 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 .