Java InputStream en chaîne

1. Vue d’ensemble

Dans ce tutoriel, nous verrons comment convertir un InputStream en String ** , à l’aide de Guava , du Apache Commons IO , et Java pur.

Cet article fait partie de la série “Java - Back to Basic” ici sur Baeldung.

2. Conversion avec goyave

Commençons par un exemple Guava - exploitant la fonctionnalité ByteSource :

@Test
public void givenUsingGuava__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    ByteSource byteSource = new ByteSource() {
        @Override
        public InputStream openStream() throws IOException {
            return inputStream;
        }
    };

    String text = byteSource.asCharSource(Charsets.UTF__8).read();

    assertThat(text, equalTo(originalString));
}

Passons en revue les étapes:

  • first - nous enroulons notre InputStream en une ByteSource__

conscient, c’est le moyen le plus simple de le faire alors ** - nous considérons notre ByteSource comme un CharSource avec un UTF8

jeu de caractères.

  • enfin - nous utilisons le CharSource pour le lire en tant que chaîne.

Une méthode plus simple de conversion avec Guava , mais le flux doit être explicitement fermé; Heureusement, nous pouvons simplement utiliser la syntaxe try-with-resources pour résoudre ce problème:

@Test
public void givenUsingGuavaAndJava7__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = null;
    try (final Reader reader = new InputStreamReader(inputStream)) {
        text = CharStreams.toString(reader);
    }

    assertThat(text, equalTo(originalString));
}

3. Conversion avec Apache Commons IO

Voyons maintenant comment procéder avec la bibliothèque Commons IO.

Une mise en garde importante ici est que - contrairement à Guava - aucun de ces exemples ne fermera le InputStream - c’est pourquoi je préfère personnellement la solution de Guava.

@Test
public void givenUsingCommonsIo__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = IOUtils.toString(inputStream, StandardCharsets.UTF__8.name());
    assertThat(text, equalTo(originalString));
}

Nous pouvons également utiliser un StringWriter pour effectuer la conversion:

@Test
public void givenUsingCommonsIoWithCopy__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    StringWriter writer = new StringWriter();
    String encoding = StandardCharsets.UTF__8.name();
    IOUtils.copy(inputStream, writer, encoding);

    assertThat(writer.toString(), equalTo(originalString));
}

4. Conversion avec Java - InputStream

Examinons maintenant une approche de niveau inférieur utilisant Java pur - un InputStream et un simple StringBuilder :

@Test
public void givenUsingJava5__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(DEFAULT__SIZE);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    StringBuilder textBuilder = new StringBuilder();
    try (Reader reader = new BufferedReader(new InputStreamReader
      (inputStream, Charset.forName(StandardCharsets.UTF__8.name())))) {
        int c = 0;
        while ((c = reader.read()) != -1) {
            textBuilder.append((char) c);
        }
    }
    assertEquals(textBuilder.toString(), originalString);
}

5. Conversion avec Java et un Scanner

Ensuite - regardons un exemple simple en Java - en utilisant un texte standard Scanner :

@Test
public void givenUsingJava7__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    String text = null;
    try (Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF__8.name())) {
        text = scanner.useDelimiter("\\A").next();
    }

    assertThat(text, equalTo(originalString));
}

Notez que le InputStream va être fermé par la fermeture du Scanner .

La seule raison pour laquelle il s’agit d’un exemple Java 7, et non de Java 5, c’est l’utilisation de l’instruction try-with-resources - le transformer en un bloc standard try-finally se compilera parfaitement avec Java 5 .

6. Conversion à l’aide de ByteArrayOutputStream

Enfin, examinons un autre exemple Java simple, utilisant cette fois la classe ByteArrayOutputStream :

@Test
public final void givenUsingPlainJava__whenConvertingAnInputStreamToString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(8);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int nRead;
    byte[]data = new byte[1024];
    while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, nRead);
    }

    buffer.flush();
    byte[]byteArray = buffer.toByteArray();

    String text = new String(byteArray, StandardCharsets.UTF__8);
    assertThat(text, equalTo(originalString));
}

Dans cet exemple, le InputStream est d’abord converti en un ByteArrayOutputStream en lisant et en écrivant des blocs d’octets, puis le OutputStream est transformé en un tableau d’octets utilisé pour créer un String .

7. Conversion avec java.nio

Une autre solution consiste à copier le contenu de InputStream dans un fichier, puis à le convertir en String:

@Test
public final void givenUsingTempFile__whenConvertingAnInputStreamToAString__thenCorrect()
  throws IOException {
    String originalString = randomAlphabetic(DEFAULT__SIZE);
    InputStream inputStream = new ByteArrayInputStream(originalString.getBytes());

    Path tempFile = Files.createTempDirectory("").resolve(UUID.randomUUID().toString() + ".tmp");
    Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE__EXISTING);
    String result = new String(Files.readAllBytes(tempFile));

    assertThat(result, equalTo(originalString));
}

Ici, nous utilisons la classe java.nio.file.Files pour créer un fichier temporaire et pour copier le contenu de InputStream dans le fichier.

Ensuite, la même classe est utilisée pour convertir le contenu du fichier en String avec la méthode readAllBytes () .

8. Conclusion

Après avoir compilé de manière correcte et lisible la conversion simple - InputStream to String - et après avoir vu tant de réponses et de solutions extrêmement différentes, je pense qu’une bonne pratique claire et concise est requise .

La mise en œuvre de tous ces exemples et extraits de code est disponible à l’adresse GitHub - il s’agit d’un projet basé sur Maven, devrait être facile à importer et à exécuter tel quel.