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

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

1. обзор

В этой статье мы рассмотрим классStreamUtils и то, как мы можем его использовать.

Проще говоря,StreamUtils - это класс Spring, который содержит некоторые служебные методы для работы с потоком -InputStream иOutputStream, которые находятся в пакетеjava.io и не связаны с Java 8. Stream API.

2. Maven Dependency

КлассStreamUtils доступен в модуле spring-core, поэтому давайте добавим его в нашpom.xml:


    org.springframework
    spring-core
    5.1.4.RELEASE

Вы можете найти последнюю версию библиотеки наMaven Central Repository.

3. Копирование потоков

КлассStreamUtils содержит несколько перегруженных методов с именемcopy(), а также некоторые другие варианты:

  • copyRange ()

  • 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 и возвращает его содержимое как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() принимает три параметра:String для копирования,Charset, который мы хотим использовать для записи в файл, иOutputStream, который мы хотим скопировать. содержаниеString к.

Вот как мы можем скопировать содержимое данногоInputStream в новыйString:

@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);

Мы также можем использовать метод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 и увидели, как их можно использовать.

Полную реализацию этого руководства можно найти вover on GitHub.