Java InputStream na reťazec

1. Prehľad

V tomto výučbe sa pozrieme na ako previesť InputStream na strunupomocou Guavy, knižnice Apache Commons IO a obyčajnej Javy.

Tento článok je súčasťou série „Java - Späť na základné“ tu na Baeldungu.

2. Konverzia pomocou nástroja Guava

Začnime príkladom Guava - využitím ByteSource funkčnosť:

@ Test public void givenUsingGuava_whenConvertingAnInputStreamToAString_thenCorrect () vyvolá IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nový ByteArrayInputStream (originalString.getBytes ()); ByteSource byteSource = nový ByteSource () {@Override public InputStream openStream () vyvolá IOException {return inputStream; }}; Reťazec text = byteSource.asCharSource (Charsets.UTF_8) .read (); assertThat (text, equalTo (originalString)); }

Prejdime si kroky:

  • najprv - zabalíme naše InputStream a ByteSource - a pokiaľ viem, je to najjednoduchší spôsob, ako to urobiť
  • potom - pozeráme sa na naše ByteSource ako CharSource so znakovou sadou UTF8.
  • konečne - používame CharSource prečítať ako reťazec.

A jednoduchší spôsob prevedenia s Guava, ale prúd treba výslovne uzavrieť; našťastie sa o to postaráme jednoducho pomocou syntaxe try-with-resources:

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

3. Konverzia pomocou Apache Commons IO

Poďme sa teraz pozrieť na to, ako to urobiť s knižnicou Commons IO.

Dôležitou výhradou je, že na rozdiel od Guavy žiadny z týchto príkladov neuzavrie InputStream - čo je dôvod, prečo osobne uprednostňujem riešenie Guava.

@ Test public void givenUsingCommonsIo_whenConvertingAnInputStreamToAString_thenCorrect () vyvolá IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nový ByteArrayInputStream (originalString.getBytes ()); Reťazec text = IOUtils.toString (inputStream, StandardCharsets.UTF_8.name ()); assertThat (text, equalTo (originalString)); }

Môžeme tiež použiť a StringWriter vykonať konverziu:

@Test public void givenUsingCommonsIoWithCopy_whenConvertingAnInputStreamToAString_thenCorrect () hodí IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nový ByteArrayInputStream (originalString.getBytes ()); Zapisovateľ StringWriter = nový StringWriter (); Kódovanie reťazca = StandardCharsets.UTF_8.name (); IOUtils.copy (inputStream, zapisovač, kódovanie); assertThat (writer.toString (), equalTo (originalString)); }

4. Konverzia pomocou Javy - InputStream

Pozrime sa teraz na prístup na nižšej úrovni pomocou obyčajnej Java - InputStream a jednoduchý StringBuilder:

@Test public void givenUsingJava5_whenConvertingAnInputStreamToAString_thenCorrect () vyvolá IOException {String originalString = randomAlphabetic (DEFAULT_SIZE); InputStream inputStream = nový ByteArrayInputStream (originalString.getBytes ()); StringBuilder textBuilder = nový 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. Používanie Java 8

Java 8 prináša nový riadky () metóda do BufferedReader. Pozrime sa, ako ho môžeme využiť na prevod súboru InputStream do a Reťazec:

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

Je dôležité spomenúť to riadky () používa readLine () metóda pod kapotou. readLine () predpokladá, že riadok je ukončený ktorýmkoľvek z riadkov („\ n“), znakom konca riadku („\ r“) alebo znakom konca riadku, za ktorým nasleduje riadkový posuv. Inými slovami, podporuje všetko bežné Koniec riadku štýly - Unix, Windows a dokonca aj starý Mac OS.

Na druhej strane, keď používame Collectors.joining (), musíme sa výslovne rozhodnúť, ktorý typ EOL chceme pre vytvorený použiť String.

Mohli by sme použiť aj Collectors.joining (System.lineSeparator ()), v takom prípade výstup závisí od nastavení systému.

5. Konverzia pomocou Java a a Skener

Ďalej - pozrime sa na obyčajný príklad Java - pomocou štandardného textu Skener:

@Test public void givenUsingJava7_whenConvertingAnInputStreamToAString_thenCorrect () vyvolá IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nový ByteArrayInputStream (originalString.getBytes ()); Reťazcový text = null; try (Scanner scanner = new Scanner (inputStream, StandardCharsets.UTF_8.name ())) {text = scanner.useDelimiter ("\ A"). next (); } assertThat (text, equalTo (originalString)); }

Všimnite si, že InputStream sa uzavrie zatvorením Skener.

Tiež stojí za to objasniť čo useDelimiter („\ A“) robí. Tu sme prešli cez „\ A“, čo je hraničný značkový regulárny výraz, ktorý označuje začiatok vstupu. V podstate to znamená, že Ďalšie() volanie prečíta celý vstupný prúd.

Jediným dôvodom, prečo je to príklad Java 7, a nie Java 5, je použitie vyskúšajte zdroje vyhlásenie - z ktorého sa stal štandard skús-konečne blokovať sa bude kompilovať s Java 5.

6. Konverzia pomocou ByteArrayOutputStream

Na záver sa pozrime na ďalší jednoduchý príklad Java, tentokrát s použitím ByteArrayOutputStream trieda:

@Test public void givenUsingPlainJava_whenConvertingAnInputStreamToString_thenCorrect () vyvolá IOException {String originalString = randomAlphabetic (8); InputStream inputStream = nový ByteArrayInputStream (originalString.getBytes ()); ByteArrayOutputStream buffer = nový ByteArrayOutputStream (); int nRead; byte [] dáta = nový bajt [1024]; while ((nRead = inputStream.read (data, 0, data.length))! = -1) {buffer.write (data, 0, nRead); } buffer.flush (); byte [] byteArray = buffer.toByteArray (); Reťazcový text = nový Reťazec (byteArray, StandardCharsets.UTF_8); assertThat (text, equalTo (originalString)); }

V tomto príklade najskôr InputStream sa prevádza na a ByteArrayOutputStream čítaním a zápisom bajtových blokov, potom OutputStream sa transformuje na bajtové pole, ktoré sa používa na vytvorenie a String.

7. Konverzia s java.nio

Ďalším riešením je kopírovanie obsahu súboru InputStream do súboru, potom ho preveďte na a Reťazec:

@Test public void givenUsingTempFile_whenConvertingAnInputStreamToAString_thenCorrect () hodí IOException {String originalString = randomAlphabetic (DEFAULT_SIZE); InputStream inputStream = nový ByteArrayInputStream (originalString.getBytes ()); Cesta tempFile = Files.createTempDirectory (""). Resolve (UUID.randomUUID (). ToString () + ".tmp"); Files.copy (inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); Výsledok reťazca = nový reťazec (Files.readAllBytes (tempFile)); assertThat (result, equalTo (originalString)); }

Tu používame java.nio.file.files triedy na vytvorenie dočasného súboru a kopírovanie obsahu súboru InputStream do spisu. Potom sa rovnaká trieda použije na prevod obsahu súboru na a String s readAllBytes () metóda.

8. Záver

Po zostavení najlepšieho spôsobu, ako urobiť jednoduchú konverziu - InputStream na String - správnym a čitateľným spôsobom - a potom, čo som videl toľko divoko odlišných odpovedí a riešení - si myslím, že vyžaduje sa jasný a výstižný osvedčený postup.

Implementácia všetkých týchto príkladov a útržkov kódu nájdete na GitHub - toto je projekt založený na Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.