Java InputStream to String

1. Übersicht

In diesem Tutorial erfahren Sie, wie Sie einen InputStream mithilfe von Guava, der Apache Commons IO-Bibliothek und einfachem Java in einen String konvertieren .

Dieser Artikel ist Teil der Reihe „Java - Back to Basic“ hier auf Baeldung.

2. Konvertieren mit Guave

Beginnen wir mit einem Guava-Beispiel - Nutzung der ByteSource- Funktionalität:

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

Gehen wir die Schritte durch:

  • Zuerst - wir verpacken unseren InputStream in eine ByteSource - und soweit mir bekannt ist, ist dies der einfachste Weg, dies zu tun
  • dann - wir betrachten unsere ByteSource als CharSource mit einem UTF8-Zeichensatz.
  • Schließlich verwenden wir die CharSource , um sie als String zu lesen.

Eine einfachere Möglichkeit, die Konvertierung mit Guava durchzuführen , aber der Stream muss explizit geschlossen werden. Zum Glück können wir einfach die Try-with-Resources-Syntax verwenden, um dies zu erledigen:

@Test public void givenUsingGuavaAndJava7_whenConvertingAnInputStreamToAString_thenCorrect() throws IOException { String originalString = randomAlphabetic(8); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = null; try (Reader reader = new InputStreamReader(inputStream)) { text = CharStreams.toString(reader); } assertThat(text, equalTo(originalString)); }

3. Konvertieren mit Apache Commons IO

Schauen wir uns nun an, wie dies mit der Commons IO-Bibliothek gemacht wird.

Eine wichtige Einschränkung hierbei ist, dass im Gegensatz zu Guava keines dieser Beispiele den InputStream schließt. Deshalb bevorzuge ich persönlich die Guava-Lösung.

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

Wir können auch einen StringWriter verwenden , um die Konvertierung durchzuführen :

@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. Konvertieren mit Java - InputStream

Schauen wir uns nun einen Ansatz auf niedrigerer Ebene mit einfachem Java an - einen InputStream und einen einfachen 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); }

4.1. Verwenden von Java 8

Java 8 bringt eine neue lines () -Methode in den BufferedReader . Mal sehen, wie wir damit einen InputStream in einen String konvertieren können :

@Test public void givenUsingJava8_whenConvertingAnInputStreamToAString_thenCorrect() { String originalString = randomAlphabetic(DEFAULT_SIZE); InputStream inputStream = new ByteArrayInputStream(originalString.getBytes()); String text = new BufferedReader( new InputStreamReader(inputStream, StandardCharsets.UTF_8))) .lines() .collect(Collectors.joining("\n")); assertThat(text, equalTo(originalString)); }

Es ist wichtig zu erwähnen, dass lines () die readLine () -Methode unter der Haube verwendet. readLine () geht davon aus, dass eine Zeile durch einen Zeilenvorschub ("\ n"), einen Wagenrücklauf ("\ r") oder einen Wagenrücklauf, unmittelbar gefolgt von einem Zeilenvorschub, beendet wird. Mit anderen Worten, es werden alle gängigen End Of Line- Stile unterstützt - Unix, Windows und sogar altes Mac OS.

Auf der anderen Seite, wenn wir verwenden Collectors.joining () , müssen wir explizit , welche Art von EOL entscheiden wir uns für die erstellt verwenden möchten String .

Wir könnten auch Collectors.joining (System.lineSeparator ()) verwenden . In diesem Fall hängt die Ausgabe von den Systemeinstellungen ab.

5. Konvertieren mit Java und einem Scanner

Als nächstes - schauen wir uns ein einfaches Java-Beispiel an - verwenden Sie einen Standard- Textscanner :

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

Beachten Sie, dass der InputStream durch Schließen des Scanners geschlossen wird .

Es lohnt sich auch zu klären, was useDelimiter ("\\ A") bewirkt. Hier haben wir das '\ A' übergeben, das ein Grenzmarkierungs-Regex ist, der den Beginn der Eingabe kennzeichnet. Dies bedeutet im Wesentlichen, dass der nächste () Aufruf den gesamten Eingabestream liest.

Der einzige Grund, warum dies ein Java 7-Beispiel ist und kein Java 5-Beispiel, ist die Verwendung der try-with-resources- Anweisung. Wenn Sie diese in einen Standard- try-finally- Block umwandeln, wird dies mit Java 5 problemlos kompiliert .

6. Konvertieren mit ByteArrayOutputStream

Schauen wir uns zum Schluss ein weiteres einfaches Java-Beispiel an, diesmal mit der ByteArrayOutputStream- Klasse:

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

In diesem Beispiel wird der InputStream zuerst durch Lesen und Schreiben von Byteblöcken in einen ByteArrayOutputStream konvertiert , dann wird der OutputStream in ein Byte-Array transformiert, mit dem ein String erstellt wird .

7. Konvertieren mit java.nio

Eine andere Lösung besteht darin, den Inhalt des InputStream in eine Datei zu kopieren und diesen dann in einen String zu konvertieren :

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

Hier verwenden wir die Klasse java.nio.file.Files , um eine temporäre Datei zu erstellen und den Inhalt des InputStream in die Datei zu kopieren . Anschließend wird dieselbe Klasse verwendet, um den Dateiinhalt mit der Methode readAllBytes () in einen String zu konvertieren .

8. Fazit

Nachdem ich den besten Weg für die einfache Konvertierung - InputStream to String - korrekt und lesbar kompiliert und so viele völlig unterschiedliche Antworten und Lösungen gesehen habe, denke ich, dass eine klare und präzise Best Practice dafür erforderlich ist .

Die Implementierung all dieser Beispiele und Codefragmente finden Sie auf GitHub - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.