Java InputStream naar String

1. Overzicht

In deze tutorial zullen we kijken naar hoe je een InputStream aan een String, met behulp van Guava, de Apache Commons IO-bibliotheek en gewoon Java.

Dit artikel maakt deel uit van de serie "Java - Back to Basic" hier op Baeldung.

2. Converteren met guave

Laten we beginnen met een Guava-voorbeeld: gebruikmakend van de ByteSource functionaliteit:

@ Test openbare ongeldige gegevenUsingGuava_whenConvertingAnInputStreamToAString_thenCorrect () gooit IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nieuwe ByteArrayInputStream (originalString.getBytes ()); ByteSource byteSource = nieuwe ByteSource () {@Override openbare InputStream openStream () gooit IOException {return inputStream; }}; String text = byteSource.asCharSource (Charsets.UTF_8) .read (); assertThat (text, equalTo (originalString)); }

Laten we de stappen eens doornemen:

  • eerste - we pakken onze in InputStream een ByteSource - en voor zover ik weet, is dit de gemakkelijkste manier om dit te doen
  • dan - we bekijken onze ByteSource als een CharSource met een UTF8-karakterset.
  • Tenslotte - wij gebruiken de CharSource om het als een string te lezen.

EEN eenvoudigere manier om de conversie uit te voeren met Guava, maar de stream moet expliciet worden gesloten; gelukkig kunnen we gewoon de try-with-resources-syntaxis gebruiken om daarvoor te zorgen:

@Test openbare leegte gegevenUsingGuavaAndJava7_whenConvertingAnInputStreamToAString_thenCorrect () gooit IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nieuwe ByteArrayInputStream (originalString.getBytes ()); String text = null; probeer (Reader reader = nieuwe InputStreamReader (inputStream)) {text = CharStreams.toString (reader); } assertThat (text, equalTo (originalString)); }

3. Converteren met Apache Commons IO

Laten we nu eens kijken hoe u dit kunt doen met de Commons IO-bibliotheek.

Een belangrijk voorbehoud hierbij is dat - in tegenstelling tot Guava - geen van deze voorbeelden de InputStream - daarom geef ik persoonlijk de voorkeur aan de Guava-oplossing.

@Test openbare leegte gegevenUsingCommonsIo_whenConvertingAnInputStreamToAString_thenCorrect () gooit IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nieuwe ByteArrayInputStream (originalString.getBytes ()); String text = IOUtils.toString (inputStream, StandardCharsets.UTF_8.name ()); assertThat (text, equalTo (originalString)); }

We kunnen ook een StringWriter om de conversie uit te voeren:

@Test openbare leegte gegevenUsingCommonsIoWithCopy_whenConvertingAnInputStreamToAString_thenCorrect () gooit IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nieuwe ByteArrayInputStream (originalString.getBytes ()); StringWriter-schrijver = nieuwe StringWriter (); String-codering = StandardCharsets.UTF_8.name (); IOUtils.copy (inputStream, schrijver, codering); assertThat (writer.toString (), equalTo (originalString)); }

4. Converteren met Java - InputStream

Laten we nu kijken naar een benadering op een lager niveau met behulp van gewoon Java - een InputStream en een eenvoudig StringBuilder:

@ Test openbare ongeldige gegevenUsingJava5_whenConvertingAnInputStreamToAString_thenCorrect () gooit IOException {String originalString = randomAlphabetic (DEFAULT_SIZE); InputStream inputStream = nieuwe ByteArrayInputStream (originalString.getBytes ()); StringBuilder textBuilder = nieuwe StringBuilder (); probeer (Reader reader = nieuwe BufferedReader (nieuwe 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. Java 8 gebruiken

Java 8 brengt een nieuw lijnen () methode naar de BufferedReader. Laten we eens kijken hoe we het kunnen gebruiken om een InputStream naar een Draad:

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

Het is belangrijk om dat te vermelden lijnen () gebruikt de Lees regel() methode onder de motorkap. Lees regel() gaat ervan uit dat een regel wordt beëindigd door een regel feed ("\ n"), een regelterugloop ("\ r") of een regelterugloop onmiddellijk gevolgd door een regelinvoer. Met andere woorden, het ondersteunt al het algemene Einde van de lijn stijlen - Unix, Windows en zelfs oud Mac OS.

Aan de andere kant, wanneer we gebruiken Collectors.joining (), moeten we expliciet beslissen welk type EOL we willen gebruiken voor het gecreëerde Draad.

We kunnen ook de Collectors.joining (System.lineSeparator ()), in welk geval de output afhankelijk is van de systeeminstellingen.

5. Converteren met Java en een Scanner

Laten we vervolgens - laten we naar een gewoon Java-voorbeeld kijken - een standaardtekst gebruiken Scanner:

@Test openbare leegte gegevenUsingJava7_whenConvertingAnInputStreamToAString_thenCorrect () gooit IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nieuwe ByteArrayInputStream (originalString.getBytes ()); String text = null; probeer (Scanner scanner = nieuwe scanner (inputStream, StandardCharsets.UTF_8.name ())) {text = scanner.useDelimiter ("\ A"). next (); } assertThat (text, equalTo (originalString)); }

Merk op dat de InputStream wordt gesloten door het sluiten van de Scanner.

Het is ook de moeite waard om te verduidelijken wat useDelimiter ("\ A") doet. Hier passeerden we de ‘\ A ', een regex voor de grensmarkering die het begin van de invoer aangeeft. In wezen betekent dit dat de De volgende() call leest de volledige invoerstroom.

De enige reden dat dit een Java 7-voorbeeld is en niet een Java 5-voorbeeld, is het gebruik van de probeer-met-middelen statement - dat in een standaard veranderen probeer het eindelijk blok zal prima compileren met Java 5.

6. Converteren met ByteArrayOutputStream

Laten we tot slot nog een ander gewoon Java-voorbeeld bekijken, dit keer met behulp van de ByteArrayOutputStream klasse:

@Test openbare leegte gegevenUsingPlainJava_whenConvertingAnInputStreamToString_thenCorrect () gooit IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nieuwe ByteArrayInputStream (originalString.getBytes ()); ByteArrayOutputStream-buffer = nieuwe ByteArrayOutputStream (); int nRead; byte [] data = nieuwe byte [1024]; while ((nRead = inputStream.read (data, 0, data.length))! = -1) {buffer.write (data, 0, nRead); } buffer.flush (); byte [] byteArray = buffer.toByteArray (); String text = nieuwe String (byteArray, StandardCharsets.UTF_8); assertThat (text, equalTo (originalString)); }

In dit voorbeeld moet eerst de InputStream wordt geconverteerd naar een ByteArrayOutputStream door byteblokken te lezen en te schrijven, en vervolgens de OutputStream wordt getransformeerd naar een byte-array, die wordt gebruikt om een Draad.

7. Omzetten met java.nio

Een andere oplossing is om de inhoud van het InputStream naar een bestand en converteer dit vervolgens naar een Draad:

@Test openbare leegte gegevenUsingTempFile_whenConvertingAnInputStreamToAString_thenCorrect () gooit IOException {String originalString = randomAlphabetic (DEFAULT_SIZE); InputStream inputStream = nieuwe ByteArrayInputStream (originalString.getBytes ()); Pad tempFile = Files.createTempDirectory (""). Resolven (UUID.randomUUID (). ToString () + ".tmp"); Files.copy (inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); String resultaat = nieuwe String (Files.readAllBytes (tempFile)); assertThat (resultaat, gelijk aan (originalString)); }

Hier gebruiken we de java.nio.file.Files class om een ​​tijdelijk bestand te maken en de inhoud van het InputStream naar het bestand. Vervolgens wordt dezelfde klasse gebruikt om de bestandsinhoud naar een Draad met de readAllBytes () methode.

8. Conclusie

Na het samenstellen van de beste manier om de eenvoudige conversie - InputStream naar String - op een correcte en leesbare manier uit te voeren - en na het zien van zoveel enorm verschillende antwoorden en oplossingen - denk ik dat hiervoor is een duidelijke en beknopte beste praktijk vereist.

De implementatie van al deze voorbeelden en codefragmenten is te vinden op GitHub - dit is een op Maven gebaseerd project, dus het zou gemakkelijk moeten kunnen worden geïmporteerd en uitgevoerd zoals het is.