Java InputStream ke String

1. Ikhtisar

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

Artikel ini adalah bagian dari seri “Java - Kembali ke Dasar” di Baeldung.

2. Mengonversi Dengan Jambu Biji

Mari kita mulai dengan contoh Guava - memanfaatkan fungsionalitas 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 kita bahas langkah-langkahnya:

  • pertama - kita membungkus InputStream a ByteSource - dan sejauh yang saya tahu, ini adalah cara termudah untuk melakukannya
  • kemudian - kami melihat ByteSource kami sebagai CharSource dengan charset UTF8.
  • akhirnya - kami menggunakan CharSource untuk membacanya sebagai String.

Cara yang lebih sederhana untuk melakukan konversi dengan Jambu biji , tetapi aliran harus ditutup secara eksplisit; untungnya, kita cukup menggunakan sintaks try-with-resources untuk mengatasinya:

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

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

Peringatan penting di sini adalah bahwa - tidak seperti Guava - tidak satu pun dari contoh ini yang akan menutup InputStream - itulah sebabnya saya pribadi lebih memilih solusi Guava.

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

Kita juga bisa menggunakan StringWriter untuk melakukan konversi:

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

Sekarang mari kita lihat pendekatan tingkat yang lebih rendah 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 metode lines () baru ke BufferedReader . Mari kita lihat bagaimana kita dapat memanfaatkannya untuk mengubah InputStream menjadi 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 disebutkan bahwa lines () menggunakan metode readLine () di bawah tenda. readLine () mengasumsikan bahwa sebuah baris diakhiri oleh salah satu dari feed baris ("\ n"), carriage return ("\ r"), atau carriage return diikuti segera oleh linefeed. Dengan kata lain, ini mendukung semua gaya End Of Line yang umum - Unix, Windows, dan bahkan Mac OS lama.

Di sisi lain, ketika kita menggunakan Collectors.joining () , kita perlu secara eksplisit memutuskan jenis EOL mana yang ingin kita gunakan untuk String yang dibuat .

Kita juga bisa menggunakan Collectors.joining (System.lineSeparator ()) , dalam hal ini keluarannya tergantung pada pengaturan sistem.

5. Mengkonversi Dengan Java dan Scanner

Selanjutnya - mari kita lihat contoh Java biasa - menggunakan Pemindai teks standar :

@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 bahwa InputStream akan ditutup dengan penutupan Scanner .

Ada baiknya juga mengklarifikasi apa yang dilakukan useDelimiter ("\\ A") . Di sini, kami melewati '\ A' yang merupakan regex penanda batas yang menunjukkan awal input. Pada dasarnya, ini berarti bahwa panggilan next () membaca seluruh aliran input.

Satu-satunya alasan ini adalah contoh Java 7, dan bukan Java 5 adalah penggunaan pernyataan try-with-resources - mengubahnya menjadi blok coba-akhirnya standar akan dikompilasi dengan baik dengan Java 5 .

6. Konversi Menggunakan ByteArrayOutputStream

Terakhir, mari kita lihat contoh Java biasa lainnya, 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 diubah menjadi ByteArrayOutputStream dengan membaca dan menulis blok byte, kemudian OutputStream diubah menjadi array byte, yang digunakan untuk membuat String .

7. Mengubah Dengan java.nio

Solusi lain adalah menyalin konten InputStream ke file, lalu mengubahnya 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 file sementara, serta menyalin konten InputStream ke file. Kemudian, kelas yang sama digunakan untuk mengonversi konten file menjadi String dengan metode readAllBytes () .

8. Kesimpulan

Setelah menyusun cara terbaik untuk melakukan konversi sederhana - InputStream ke String - dengan cara yang benar dan dapat dibaca - dan setelah melihat begitu banyak jawaban dan solusi yang sangat berbeda - saya pikir praktik terbaik yang jelas dan ringkas untuk ini diperlukan .

Penerapan semua contoh dan cuplikan kode ini dapat ditemukan di GitHub - ini adalah proyek berbasis Maven, jadi semestinya mudah untuk mengimpor dan menjalankan apa adanya.