Java InputStream til streng

1. Oversigt

I denne vejledning ser vi på hvordan man konverterer en InputStream til en streng, ved hjælp af Guava, Apache Commons IO-biblioteket og almindelig Java.

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

2. Konvertering med Guava

Lad os starte med et Guava-eksempel - udnytte ByteSource funktionalitet:

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

Lad os gå over trinnene:

  • først - vi pakker vores ind InputStream -en ByteSource - og så vidt jeg ved, er dette den nemmeste måde at gøre det på
  • derefter - vi ser vores ByteSource som en CharSource med et UTF8-tegnsæt.
  • langt om længe - vi bruger CharSource at læse det som en streng.

EN enklere måde at udføre konverteringen med Guava på, men strømmen skal lukkes eksplicit; Heldigvis kan vi simpelthen bruge syntaksen for at prøve ressourcer til at tage sig af det:

@Test offentlig ugyldighed 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

Lad os nu se på, hvordan man gør dette med Commons IO-biblioteket.

En vigtig advarsel her er, at - i modsætning til Guava - ingen af ​​disse eksempler vil lukke InputStream - derfor foretrækker jeg personligt Guava-løsningen.

@Test offentlig ugyldighed 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å bruge en StringWriter at gøre konverteringen:

@Test offentlig ugyldighed givenUsingCommonsIoWithCopy_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (8); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); StringWriter-forfatter = ny StringWriter (); Strengkodning = StandardCharsets.UTF_8.name (); IOUtils.copy (inputStream, forfatter, kodning); assertThat (writer.toString (), equalTo (originalString)); }

4. Konvertering med Java - InputStream

Lad os se på en tilgang på et lavere niveau ved hjælp af almindelig Java - en InputStream og en simpel StringBuilder:

@Test offentlig ugyldighed givenUsingJava5_whenConvertingAnInputStreamToAString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (DEFAULT_SIZE); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); StringBuilder textBuilder = ny StringBuilder (); prøv (Reader reader = new BufferedReader (new 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. Brug af Java 8

Java 8 bringer et nyt linjer () metode til BufferedReader. Lad os se, hvordan vi kan bruge det til at konvertere en InputStream til en Snor:

@Test offentlig ugyldighed 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 vigtigt at nævne det linjer () bruger readLine () metode under emhætten. readLine () antager, at en linje afsluttes af en hvilken som helst af en linjefodring ("\ n"), en vognretur ("\ r") eller en vognretur efterfulgt straks af en linefeed. Med andre ord understøtter det alt det fælles Slut på linjen stilarter - Unix, Windows og endda gamle Mac OS.

På den anden side, når vi bruger Collectors.joining (), skal vi eksplicit beslutte, hvilken type EOL vi vil bruge til den oprettede Snor.

Vi kunne også bruge Collectors.joining (System.lineSeparator ()), i hvilket tilfælde output afhænger af systemindstillingerne.

5. Konvertering med Java og en Scanner

Dernæst - lad os se på et almindeligt Java-eksempel - ved hjælp af en standardtekst Scanner:

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

Bemærk, at InputStream vil blive lukket ved lukning af Scanner.

Det er også værd at afklare hvad useDelimiter (“\ A”) gør. Her passerede vi '\ A', som er en grænse markør regex, der angiver begyndelsen af ​​input. I det væsentlige betyder det, at Næste() opkald læser hele inputstrømmen.

Den eneste grund til, at dette er et Java 7-eksempel, og ikke en Java 5, er brugen af prøv med ressourcer udsagn - at gøre det til en standard prøv endelig blok kompilerer fint med Java 5.

6. Konvertering ved hjælp af ByteArrayOutputStream

Lad os endelig se på et andet almindeligt Java-eksempel, denne gang ved hjælp af ByteArrayOutputStream klasse:

@Test offentlig ugyldighed givenUsingPlainJava_whenConvertingAnInputStreamToString_thenCorrect () kaster IOException {String originalString = randomAlphabetic (8); InputStream inputStream = ny ByteArrayInputStream (originalString.getBytes ()); ByteArrayOutputStream-buffer = ny ByteArrayOutputStream (); int nLæs; 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 eksempel først, InputStream konverteres til en ByteArrayOutputStream ved at læse og skrive byteblokke, derefter OutputStream transformeres til et byte-array, som bruges til at oprette et Snor.

7. Konvertering med java.nio

En anden løsning er at kopiere indholdet af InputStream til en fil, og konverter den derefter til en Snor:

@Test offentlig ugyldighed 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 bruger vi java.nio.file.Files klasse for at oprette en midlertidig fil samt kopiere indholdet af InputStream til filen. Derefter bruges den samme klasse til at konvertere filindholdet til en Snor med readAllBytes () metode.

8. Konklusion

Efter at have sammensat den bedste måde at udføre den enkle konvertering - InputStream til String - på en korrekt og læsbar måde - og efter at have set så mange vildt forskellige svar og løsninger - tror jeg, at der kræves en klar og kortfattet bedste praksis for dette.

Implementeringen af ​​alle disse eksempler og kodestykker kan findes på GitHub - dette er et Maven-baseret projekt, så det skal være let at importere og køre som det er.