Introduction à Spring’s StreamUtils

Introduction à Spring’s StreamUtils

1. Vue d'ensemble

Dans cet article, nous allons voir la classeStreamUtils et comment nous pouvons l'utiliser.

En termes simples,StreamUtils est une classe de Spring qui contient des méthodes utilitaires pour traiter les flux -InputStream etOutputStream qui résident dans le packagejava.io et non liés aux Java 8 API Stream.

2. Dépendance Maven

La classeStreamUtils est disponible dans le module spring-core donc ajoutons-la à nospom.xml:


    org.springframework
    spring-core
    5.1.4.RELEASE

Vous pouvez trouver la dernière version de la bibliothèque auMaven Central Repository.

3. Copie de flux

La classeStreamUtils contient plusieurs méthodes surchargées nomméescopy() ainsi que quelques autres variantes:

  • copyRange ()

  • copyToByteArray ()

  • copyString ()

Nous pouvons copier des flux sans utiliser aucune bibliothèque. Cependant, le code va être lourd et beaucoup plus difficile à lire et à comprendre.

Notez que nous omettons de fermer les flux par souci de simplicité.

Voyons comment nous pouvons copier le contenu d'unInputStream vers unOutputStream donné:

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

Le fichier créé contient le contenu desInputStream.

Notez quegetStringFromInputStream() est une méthode qui prend unInputStream et renvoie son contenu sous forme deString. L'implémentation de la méthode est disponible dans la version complète du code.

Nous n'avons pas à copier tout le contenu desInputStream, nous pouvons copier une plage du contenu vers unOutputStream donné en utilisant la méthodecopyRange():

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

Comme nous pouvons le voir ici, lecopyRange() prend quatre paramètres, leInputStream, leOutputStream, la position à partir de laquelle commencer la copie et la position à laquelle terminer la copie. Mais que se passe-t-il si la plage spécifiée dépasse la longueur desInputStream? La méthodecopyRange() copie ensuite jusqu'à la fin du flux.

Voyons comment nous pouvons copier le contenu d'unString vers unOutputStream donné:

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

La méthodecopy() prend trois paramètres - lesString à copier, lesCharset que nous voulons utiliser pour écrire dans le fichier et lesOutputStream que nous voulons copier le contenu desString à.

Voici comment copier le contenu d'unInputStream donné vers un nouveauString:

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

Nous pouvons également copier le contenu d'un tableau d'octets donné dans unOutputStream:

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

Ou, nous pouvons copier le contenu d'unInputStream donné dans un nouveau tableau d'octets:

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. Autre fonctionnalité

UnInputStream peut être passé comme argument à la méthodedrain() pour supprimer toutes les données restantes dans le flux:

StreamUtils.drain(in);

Nous pouvons également utiliser la méthodeemptyInput() pour obtenir unInputStream vide efficace:

public InputStream getInputStream() {
    return StreamUtils.emptyInput();
}

Il existe deux méthodes surchargées nomméesnonClosing(). UnInputStream ou unOutputStream peut être passé en argument à ces méthodes pour obtenir une variante deInputStream ouOutputStream qui ignore les appels à la méthodeclose():

public InputStream getNonClosingInputStream() throws IOException {
    InputStream in = new FileInputStream("src/test/resources/input.txt");
    return StreamUtils.nonClosing(in);
}

5. Conclusion

Dans ce rapide tutoriel, nous avons vu ce que sont lesStreamUtils. Nous avons également couvert toutes les méthodes de la classeStreamUtils, et nous avons vu comment nous pouvons les utiliser.

L'implémentation complète de ce tutoriel peut être trouvéeover on GitHub.