Рубрики
Без рубрики

Введение в Spring’s StreamUtils

Откройте для себя класс StreamUtils Spring.

Автор оригинала: baeldung.

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 .