Java InputStream to String

1. Gambaran keseluruhan

Dalam tutorial ini kita akan melihat cara mengubah InputStream menjadi String , menggunakan Jambu, pustaka Apache Commons IO, dan Java biasa.

Artikel ini adalah sebahagian daripada siri "Java - Back to Basic" di Baeldung.

2. Bertukar Dengan Jambu Batu

Mari kita mulakan dengan contoh Jambu Batu - memanfaatkan fungsi ByteSource :

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

Mari ikuti langkah-langkahnya:

  • pertama - kami membungkus InputStream a ByteSource kami - dan setahu saya, ini adalah kaedah termudah untuk melakukannya
  • kemudian - kami melihat ByteSource kami sebagai CharSource dengan charset UTF8.
  • akhirnya - kami menggunakan CharSource untuk membacanya sebagai Rentetan.

Cara yang lebih mudah untuk melakukan penukaran dengan Jambu Batu , tetapi aliran itu mesti ditutup secara eksplisit; untungnya, kita hanya boleh menggunakan sintaks cuba-dengan-sumber untuk mengurus:

@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. Menukar Dengan Apache Commons IO

Sekarang mari kita lihat bagaimana melakukan ini dengan perpustakaan Commons IO.

Peringatan penting di sini adalah bahawa - berbanding Guava - kedua-dua contoh ini tidak akan menutup InputStream - sebab itulah saya secara peribadi lebih suka penyelesaian Jambu Batu.

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

Kami juga boleh menggunakan StringWriter untuk melakukan penukaran:

@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. Menukar Dengan Java - InputStream

Mari kita lihat sekarang pada pendekatan tingkat bawah menggunakan Java biasa - InputStream dan StringBuilder sederhana :

@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. Menggunakan Java 8

Java 8 membawa kaedah baris baru () ke BufferedReader . Mari lihat bagaimana kita dapat memanfaatkannya untuk menukar InputStream ke String:

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

Penting untuk menyebut bahawa garis () menggunakan kaedah readLine () di bawah tudung. readLine () menganggap bahawa garis ditamatkan oleh salah satu dari feed line (“\ n”), return kereta (“\ r”), atau return kereta diikuti dengan lineline. Dengan kata lain, ia menyokong semua gaya End Of Line yang biasa - Unix, Windows, dan juga Mac OS lama.

Sebaliknya, ketika kita menggunakan Collectors.joining () , kita perlu memutuskan secara jelas jenis EOL mana yang ingin kita gunakan untuk String yang dibuat .

Kita juga dapat menggunakan Collectors.joining (System.lineSeparator ()) , yang mana outputnya bergantung pada pengaturan sistem.

5. Menukar Dengan Java dan Pengimbas

Seterusnya - mari kita lihat contoh Java biasa - menggunakan Pengimbas teks standard :

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

Perhatikan bahawa InputStream akan ditutup dengan penutupan Scanner .

Ia juga perlu dijelaskan apa yang dilakukan oleh penggunaanDelimiter (“\\ A”) . Di sini, kami melewati '\ A' yang merupakan regex penanda sempadan yang menunjukkan permulaan input. Pada asasnya, ini bermaksud bahawa () panggilan seterusnya membaca keseluruhan aliran input.

Satu-satunya sebab ini adalah contoh Java 7, dan bukan Java 5 adalah penggunaan pernyataan cuba-dengan-sumber - mengubahnya menjadi blok percubaan akhirnya akan dikompilasi dengan baik dengan Java 5 .

6. Menukar Menggunakan ByteArrayOutputStream

Akhirnya, mari kita lihat contoh Java biasa yang lain, kali ini menggunakan kelas ByteArrayOutputStream :

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

Dalam contoh ini, pertama, InputStream ditukar menjadi ByteArrayOutputStream dengan membaca dan menulis blok bait, kemudian OutputStream diubah menjadi array byte, yang digunakan untuk membuat String .

7. Menukar Dengan java.nio

Penyelesaian lain adalah menyalin kandungan InputStream ke fail, kemudian menukarnya menjadi String:

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

Di sini, kami menggunakan kelas java.nio.file.Files untuk membuat fail sementara, dan juga menyalin kandungan InputStream ke fail. Kemudian, kelas yang sama digunakan untuk menukar kandungan fail ke String dengan kaedah readAllBytes () .

8. Kesimpulannya

Setelah menyusun kaedah terbaik untuk melakukan penukaran sederhana - InputStream to String - dengan cara yang betul dan mudah dibaca - dan setelah melihat banyak jawapan dan penyelesaian yang sangat berbeza - saya berpendapat bahawa amalan terbaik yang jelas dan ringkas untuk ini diperlukan .

Pelaksanaan semua contoh dan coretan kod ini boleh didapati di GitHub - ini adalah projek berasaskan Maven, jadi mudah untuk diimport dan dijalankan sebagaimana adanya.