Java InputStream to String

1. Oversikt

I denne opplæringen vil vi se på hvordan konvertere en InputStream til en streng, ved hjelp av Guava, Apache Commons IO-biblioteket og vanlig Java.

Denne artikkelen er en del av "Java - Back to Basic" -serien her på Baeldung.

2. Konvertering med Guava

La oss starte med et Guava-eksempel - utnytte ByteSource funksjonalitet:

@Test offentlig ugyldighet givenUsingGuava_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (8); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); ByteSource byteSource = ny ByteSource () {@ Override offentlig InputStream openStream () kaster IOException {return inputStream; }}; Strengtekst = byteSource.asCharSource (Charsets.UTF_8) .read (); assertThat (tekst, equalTo (originalString)); }

La oss gå gjennom trinnene:

  • først - vi pakker inn InputStream en ByteSource - og så vidt jeg vet er dette den enkleste måten å gjøre det på
  • deretter - vi ser på vår ByteSource som en CharSource med et UTF8-sett.
  • endelig - vi bruker CharSource å lese den som en streng.

EN enklere måte å gjøre konverteringen med Guava på, men strømmen må stenges eksplisitt; Heldigvis kan vi bare bruke syntaksen for å prøve-med-ressurser for å ta vare på det:

@Test offentlig ugyldighet givenUsingGuavaAndJava7_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (8); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); Strengtekst = null; prøv (Reader reader = new InputStreamReader (inputStream)) {text = CharStreams.toString (reader); } assertThat (text, equalTo (originalString)); }

3. Konvertering med Apache Commons IO

La oss nå se på hvordan du gjør dette med Commons IO-biblioteket.

En viktig advarsel her er at - i motsetning til Guava - vil ingen av disse eksemplene lukke InputStream - det er derfor jeg personlig foretrekker Guava-løsningen.

@Test offentlig ugyldig givenUsingCommonsIo_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (8); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); Strengtekst = IOUtils.toString (inputStream, StandardCharsets.UTF_8.name ()); assertThat (tekst, equalTo (originalString)); }

Vi kan også bruke en StringWriter å gjøre konverteringen:

@Test offentlig ugyldighet gittUsingCommonsIoWithCopy_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (8); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); StringWriter-forfatter = ny StringWriter (); Strengkoding = StandardCharsets.UTF_8.name (); IOUtils.copy (inputStream, skribent, koding); assertThat (writer.toString (), equalTo (originalString)); }

4. Konvertering med Java - InputStream

La oss se på en tilnærming på lavere nivå ved bruk av vanlig Java - en InputStream og en enkel StringBuilder:

@Test offentlig ugyldig givenUsingJava5_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (DEFAULT_SIZE); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); StringBuilder textBuilder = ny StringBuilder (); prøv (Leseleser = ny BufferedReader (ny InputStreamReader (inputStream, Charset.forName (StandardCharsets.UTF_8.name ())))) {int c = 0; mens ((c = reader.read ())! = -1) {textBuilder.append ((char) c); }} assertEquals (textBuilder.toString (), originalString); }

4.1. Bruke Java 8

Java 8 gir en ny linjer () metoden til BufferedReader. La oss se hvordan vi kan bruke den til å konvertere en InputStream til en Streng:

@Test offentlig ugyldighet givenUsingJava8_whenConvertingAnInputStreamToAString_thenCorrect () {String originalString = randomAlphabetic (DEFAULT_SIZE); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); Strengtekst = ny BufferedReader (ny InputStreamReader (inputStream, StandardCharsets.UTF_8))) .lines () .collect (Collectors.joining ("\ n")); assertThat (tekst, equalTo (originalString)); }

Det er viktig å nevne det linjer () bruker readLine () metode under panseret. readLine () antar at en linje avsluttes av en hvilken som helst av en linjemating ("\ n"), en vognretur ("\ r") eller en vognretur etterfulgt umiddelbart av en linjemating. Med andre ord støtter den alt det vanlige End Of Line stiler - Unix, Windows og til og med gamle Mac OS.

På den andre siden, når vi bruker Collectors.joining (), må vi eksplisitt bestemme hvilken type EOL vi vil bruke for den opprettet String.

Vi kan også bruke Collectors.joining (System.lineSeparator ()), i så fall avhenger av systeminnstillingene.

5. Konvertering med Java og a Skanner

Neste - la oss se på et vanlig Java-eksempel - ved hjelp av en standardtekst Skanner:

@Test offentlig ugyldighet givenUsingJava7_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (8); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); Strengtekst = null; prøv (Scanner scanner = new Scanner (inputStream, StandardCharsets.UTF_8.name ())) {text = scanner.useDelimiter ("\ A"). next (); } assertThat (text, equalTo (originalString)); }

Merk at InputStream kommer til å bli stengt ved lukking av Skanner.

Det er også verdt å avklare hva useDelimiter (“\ A”) gjør. Her passerte vi ‘\ A 'som er en grensemarkør-regex som angir begynnelsen på inngangen. I hovedsak betyr dette at neste () samtale leser hele inngangsstrømmen.

Den eneste grunnen til at dette er et Java 7-eksempel, og ikke en Java 5-en, er bruken av prøv-med-ressurser uttalelse - gjør det til en standard prøv-endelig blokkere vil kompilere helt fint med Java 5.

6. Konvertering ved hjelp av ByteArrayOutputStream

Til slutt, la oss se på et annet vanlig Java-eksempel, denne gangen ved hjelp av ByteArrayOutputStream klasse:

@Test offentlig ugyldighet givenUsingPlainJava_whenConvertingAnInputStreamToString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (8); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); ByteArrayOutputStream buffer = ny ByteArrayOutputStream (); int nLes; byte [] data = ny byte [1024]; mens ((nRead = inputStream.read (data, 0, data.length))! = -1) {buffer.write (data, 0, nRead); } buffer.flush (); byte [] byteArray = buffer.toByteArray (); Strengtekst = ny streng (byteArray, StandardCharsets.UTF_8); assertThat (tekst, equalTo (originalString)); }

I dette eksemplet, først, InputStream blir konvertert til en ByteArrayOutputStream ved å lese og skrive byteblokker, deretter OutputStream blir transformert til en byte-array, som brukes til å lage en String.

7. Konvertering med java.nio

En annen løsning er å kopiere innholdet i InputStream til en fil, og konverter denne til en Streng:

@Test offentlig ugyldighet givenUsingTempFile_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (DEFAULT_SIZE); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); Sti tempFile = Files.createTempDirectory (""). Løse (UUID.randomUUID (). ToString () + ".tmp"); Files.copy (inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); Strengresultat = ny streng (Files.readAllBytes (tempFile)); assertThat (resultat, equalTo (originalString)); }

Her bruker vi java.nio.file.Files klasse for å opprette en midlertidig fil, samt kopiere innholdet i InputStream til filen. Deretter brukes samme klasse for å konvertere filinnholdet til en String med readAllBytes () metode.

8. Konklusjon

Etter å ha samlet den beste måten å gjøre den enkle konverteringen - InputStream til String - på en riktig og lesbar måte - og etter å ha sett så mange veldig forskjellige svar og løsninger - tror jeg at en klar og kortfattet beste praksis for dette kreves.

Implementeringen av alle disse eksemplene og kodebiter kan du finne på GitHub - dette er et Maven-basert prosjekt, så det skal være enkelt å importere og kjøre som det er.