Lesen / konvertieren Sie einen InputStream in einen String

Wenn Sie ein java.io.InputStream Objekt haben, wie sollten Sie dieses Objekt verarbeiten und einen String erzeugen?


Angenommen, ich habe einen InputStream , der Textdaten enthält, und ich möchte ihn in einen String konvertieren, sodass ich ihn beispielsweise in eine Protokolldatei schreiben kann.

Was ist der einfachste Weg, den InputStream zu einem String konvertieren?

 public String convertStreamToString(InputStream is) { // ??? } 

   

Ein IOUtils Weg, dies zu tun, ist Apache commons IOUtils zu verwenden, um den InputStream in einen StringWriter zu kopieren … etwas ähnliches

 StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, encoding); String theString = writer.toString(); 

oder auch

 // NB: does not close inputStream, you'll have to use try-with-resources for that String theString = IOUtils.toString(inputStream, encoding); 

Alternativ können Sie ByteArrayOutputStream wenn Sie Ihre Streams und Writer nicht mischen möchten

Hier ist ein Weg, nur die Standard-Java-Bibliothek zu verwenden (beachten Sie, dass der Stream nicht geschlossen ist, YMMV).

 static String convertStreamToString(java.io.InputStream is) { java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; } 

Ich habe diesen Trick aus dem Artikel “Stupid Scanner Tricks” gelernt. Der Grund dafür ist, dass Scanner über Token im Stream iteriert, und in diesem Fall trennen wir Token mit “Beginn der Eingabegrenze” (\ A) und geben uns somit nur ein Token für den gesamten Inhalt des Streams.

Hinweis: Wenn Sie die Codierung des Eingabestreams genauer festlegen müssen, können Sie dem Scanner Konstruktor das zweite Argument angeben, das angibt, welcher Zeichensatz verwendet werden soll (z. B. “UTF-8”).

Huttipp geht auch an Jacob, der mich einmal auf den besagten Artikel hingewiesen hat.

EDITED: Dank einem Vorschlag von Patrick , machte die function robuster bei der Handhabung eines leeren Eingabestroms. Eine weitere Bearbeitung: nixed try / catch, Patrick ist lakonisch.

Fassen Sie andere Antworten zusammen Ich fand 11 Hauptwege, um dies zu tun (siehe unten). Und ich schrieb einige performancestests (siehe Ergebnisse unten):

Möglichkeiten, einen InputStream in einen String zu konvertieren:

  1. Verwenden von IOUtils.toString (Apache-Utils)

     String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8); 
  2. CharStreams (Guave) verwenden

     String result = CharStreams.toString(new InputStreamReader( inputStream, Charsets.UTF_8)); 
  3. Verwenden des Scanner (JDK)

     Scanner s = new Scanner(inputStream).useDelimiter("\\A"); String result = s.hasNext() ? s.next() : ""; 
  4. Verwenden der Stream-API (Java 8). Warnung : Diese Lösung konvertiert verschiedene Zeilenumbrüche (wie \r\n ) in \n .

     String result = new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n")); 
  5. Verwenden der parallelen Stream-API (Java 8). Warnung : Diese Lösung konvertiert verschiedene Zeilenumbrüche (wie \r\n ) in \n .

     String result = new BufferedReader(new InputStreamReader(inputStream)).lines() .parallel().collect(Collectors.joining("\n")); 
  6. Verwenden von InputStreamReader und StringBuilder (JDK)

     final int bufferSize = 1024; final char[] buffer = new char[bufferSize]; final StringBuilder out = new StringBuilder(); Reader in = new InputStreamReader(inputStream, "UTF-8"); for (; ; ) { int rsz = in.read(buffer, 0, buffer.length); if (rsz < 0) break; out.append(buffer, 0, rsz); } return out.toString(); 
  7. Verwenden von StringWriter und IOUtils.copy (Apache Commons)

     StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, "UTF-8"); return writer.toString(); 
  8. ByteArrayOutputStream und inputStream.read (JDK) verwenden

     ByteArrayOutputStream result = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { result.write(buffer, 0, length); } // StandardCharsets.UTF_8.name() > JDK 7 return result.toString("UTF-8"); 
  9. Verwenden von BufferedReader (JDK). Warnung: Diese Lösung konvertiert verschiedene Zeilenumbrüche (wie \n\r ) in die line.separator Systemeigenschaft (z. B. in Windows in "\ r \ n").

     String newLine = System.getProperty("line.separator"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder result = new StringBuilder(); String line; boolean flag = false; while ((line = reader.readLine()) != null) { result.append(flag? newLine: "").append(line); flag = true; } return result.toString(); 
  10. Verwenden von BufferedInputStream und ByteArrayOutputStream (JDK)

     BufferedInputStream bis = new BufferedInputStream(inputStream); ByteArrayOutputStream buf = new ByteArrayOutputStream(); int result = bis.read(); while(result != -1) { buf.write((byte) result); result = bis.read(); } // StandardCharsets.UTF_8.name() > JDK 7 return buf.toString("UTF-8"); 
  11. Verwenden von inputStream.read() und StringBuilder (JDK). Warnung : Diese Lösung hat Probleme mit Unicode, zum Beispiel mit russischem Text (funktioniert nur mit Nicht-Unicode-Text korrekt)

     int ch; StringBuilder sb = new StringBuilder(); while((ch = inputStream.read()) != -1) sb.append((char)ch); reset(); return sb.toString(); 

Warnung :

  1. Die Lösungen 4, 5 und 9 konvertieren verschiedene Zeilenumbrüche in einen.

  2. Lösung 11 kann nicht korrekt mit Unicode-Text arbeiten

performancestests

Performance-Tests für kleine String (Länge = 175), URL in GitHub (Modus = Durchschnittliche Zeit, System = Linux, Score 1.343 ist die beste):

  Benchmark Mode Cnt Score Error Units 8. ByteArrayOutputStream and read (JDK) avgt 10 1,343 ± 0,028 us/op 6. InputStreamReader and StringBuilder (JDK) avgt 10 6,980 ± 0,404 us/op 10. BufferedInputStream, ByteArrayOutputStream avgt 10 7,437 ± 0,735 us/op 11. InputStream.read() and StringBuilder (JDK) avgt 10 8,977 ± 0,328 us/op 7. StringWriter and IOUtils.copy (Apache) avgt 10 10,613 ± 0,599 us/op 1. IOUtils.toString (Apache Utils) avgt 10 10,605 ± 0,527 us/op 3. Scanner (JDK) avgt 10 12,083 ± 0,293 us/op 2. CharStreams (guava) avgt 10 12,999 ± 0,514 us/op 4. Stream Api (Java 8) avgt 10 15,811 ± 0,605 us/op 9. BufferedReader (JDK) avgt 10 16,038 ± 0,711 us/op 5. parallel Stream Api (Java 8) avgt 10 21,544 ± 0,583 us/op 

Performance-Tests für große String (Länge = 50100), URL in GitHub (Modus = Durchschnittliche Zeit, System = Linux, Score 200.715 ist die beste):

  Benchmark Mode Cnt Score Error Units 8. ByteArrayOutputStream and read (JDK) avgt 10 200,715 ± 18,103 us/op 1. IOUtils.toString (Apache Utils) avgt 10 300,019 ± 8,751 us/op 6. InputStreamReader and StringBuilder (JDK) avgt 10 347,616 ± 130,348 us/op 7. StringWriter and IOUtils.copy (Apache) avgt 10 352,791 ± 105,337 us/op 2. CharStreams (guava) avgt 10 420,137 ± 59,877 us/op 9. BufferedReader (JDK) avgt 10 632,028 ± 17,002 us/op 5. parallel Stream Api (Java 8) avgt 10 662,999 ± 46,199 us/op 4. Stream Api (Java 8) avgt 10 701,269 ± 82,296 us/op 10. BufferedInputStream, ByteArrayOutputStream avgt 10 740,837 ± 5,613 us/op 3. Scanner (JDK) avgt 10 751,417 ± 62,026 us/op 11. InputStream.read() and StringBuilder (JDK) avgt 10 2919,350 ± 1101,942 us/op 

Graphen (performancestests abhängig von der Länge des Eingabestreams im Windows 7-System)
Bildbeschreibung hier eingeben

performancestest (durchschnittliche Zeit) abhängig von der Länge des Eingabestreams im Windows 7-System:

  length 182 546 1092 3276 9828 29484 58968 test8 0.38 0.938 1.868 4.448 13.412 36.459 72.708 test4 2.362 3.609 5.573 12.769 40.74 81.415 159.864 test5 3.881 5.075 6.904 14.123 50.258 129.937 166.162 test9 2.237 3.493 5.422 11.977 45.98 89.336 177.39 test6 1.261 2.12 4.38 10.698 31.821 86.106 186.636 test7 1.601 2.391 3.646 8.367 38.196 110.221 211.016 test1 1.529 2.381 3.527 8.411 40.551 105.16 212.573 test3 3.035 3.934 8.606 20.858 61.571 118.744 235.428 test2 3.136 6.238 10.508 33.48 43.532 118.044 239.481 test10 1.593 4.736 7.527 20.557 59.856 162.907 323.147 test11 3.913 11.506 23.26 68.644 207.591 600.444 1211.545 

Apache Commons ermöglicht:

 String myString = IOUtils.toString(myInputStream, "UTF-8"); 

Natürlich könnten Sie neben UTF-8 auch andere Zeichenkodierungen wählen.

Siehe auch: ( Dokumente )

Unter Berücksichtigung der Datei sollte man zuerst eine java.io.Reader Instanz bekommen. Dies kann dann gelesen und einem StringBuilder hinzugefügt werden (wir brauchen StringBuffer wenn wir nicht in mehreren Threads darauf zugreifen und StringBuilder ist schneller). Der Trick dabei ist, dass wir in Blöcken arbeiten und daher keine anderen Pufferströme benötigen. Die Blockgröße wird für die Laufzeitleistungsoptimierung parametrisiert.

 public static String slurp(final InputStream is, final int bufferSize) { final char[] buffer = new char[bufferSize]; final StringBuilder out = new StringBuilder(); try (Reader in = new InputStreamReader(is, "UTF-8")) { for (;;) { int rsz = in.read(buffer, 0, buffer.length); if (rsz < 0) break; out.append(buffer, 0, rsz); } } catch (UnsupportedEncodingException ex) { /* ... */ } catch (IOException ex) { /* ... */ } return out.toString(); } 

Wie wäre es damit?

 InputStream in = /* your InputStream */ ; StringBuilder sb=new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String read; while((read=br.readLine()) != null) { //System.out.println(read); sb.append(read); } br.close(); return sb.toString(); 

Wenn Sie Google-Collections / Guava verwenden, können Sie Folgendes tun:

 InputStream stream = ... String content = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8)); Closeables.closeQuietly(stream); 

Beachten Sie, dass der zweite Parameter (dh Charsets.UTF_8) für den InputStreamReader nicht notwendig ist, aber es ist im Allgemeinen eine gute Idee, die Kodierung anzugeben, wenn Sie sie kennen (was Sie sollten!)

Das ist meine pure Java & Android Lösung, funktioniert gut …

 public String readFullyAsString(InputStream inputStream, String encoding) throws IOException { return readFully(inputStream).toString(encoding); } public byte[] readFullyAsBytes(InputStream inputStream) throws IOException { return readFully(inputStream).toByteArray(); } private ByteArrayOutputStream readFully(InputStream inputStream) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length = 0; while ((length = inputStream.read(buffer)) != -1) { baos.write(buffer, 0, length); } return baos; } 

Wie wäre es mit:

 import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.IOException; public static String readInputStreamAsString(InputStream in) throws IOException { BufferedInputStream bis = new BufferedInputStream(in); ByteArrayOutputStream buf = new ByteArrayOutputStream(); int result = bis.read(); while(result != -1) { byte b = (byte)result; buf.write(b); result = bis.read(); } return buf.toString(); } 

Hier ist die eleganteste Java-Lösung (ohne Bibliothek), die ich nach einigen Experimenten entwickelt habe:

 public static String fromStream(InputStream in) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder out = new StringBuilder(); String newLine = System.getProperty("line.separator"); String line; while ((line = reader.readLine()) != null) { out.append(line); out.append(newLine); } return out.toString(); } 

Zur Vollständigkeit hier ist Java 9 Lösung:

 public static String toString(InputStream input) throws IOException { return new String(input.readAllBytes(), StandardCharsets.UTF_8); } 

Die readAllBytes befindet sich derzeit in der readAllBytes JDK 9 und wird daher wahrscheinlich in der Version readAllBytes . Sie können es jetzt mit den JDK 9 Snapshot Builds versuchen.

Ich würde einige Java 8-Tricks verwenden.

 public static String streamToString(final InputStream inputStream) throws Exception { // buffering optional try ( final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)) ) { // parallel optional return br.lines().parallel().collect(Collectors.joining("\n")); } catch (final IOException e) { throw new RuntimeException(e); // whatever. } } 

Im Wesentlichen das gleiche wie einige andere Antworten, außer prägnanter.

Ich habe ein paar Tests gemacht, weil die Zeit zählt, immer.

Ich habe versucht, die Antwort in einem String 3 verschiedene Wege zu bekommen. (siehe unten)
Ich habe aus Gründen der Lesbarkeit Versuche / catch-Blöcke weggelassen.

Um Kontext zu geben, ist dies der vorangehende Code für alle 3 Ansätze:

  String response; String url = "www.blah.com/path?key=value"; GetMethod method = new GetMethod(url); int status = client.executeMethod(method); 

1)

  response = method.getResponseBodyAsString(); 

2)

 InputStream resp = method.getResponseBodyAsStream(); InputStreamReader is=new InputStreamReader(resp); BufferedReader br=new BufferedReader(is); String read = null; StringBuffer sb = new StringBuffer(); while((read = br.readLine()) != null) { sb.append(read); } response = sb.toString(); 

3)

 InputStream iStream = method.getResponseBodyAsStream(); StringWriter writer = new StringWriter(); IOUtils.copy(iStream, writer, "UTF-8"); response = writer.toString(); 

Nach 500 Tests für jeden Ansatz mit den gleichen Anfrage / Antwort-Daten, sind hier die Zahlen. Noch einmal, dies sind meine Ergebnisse und Ihre Ergebnisse sind vielleicht nicht genau die gleichen, aber ich schrieb dies, um anderen einen Hinweis auf die Effizienzunterschiede dieser Ansätze zu geben.

Ränge:
Ansatz # 1
Ansatz # 3 – 2,6% langsamer als # 1
Approach # 2 – 4,3% langsamer als # 1

Jeder dieser Ansätze ist eine geeignete Lösung, um eine Antwort zu erfassen und daraus einen String zu erstellen.

Reine Java-Lösung mit Stream s, funktioniert seit Java 8.

 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.stream.Collectors; // ... public static String inputStreamToString(InputStream is) throws IOException { try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) { return br.lines().collect(Collectors.joining(System.lineSeparator())); } } 

Wie von Christoffer Hammarström unter anderen Antworten erwähnt , ist es sicherer, den Charset explizit anzugeben. Dh Der InputStreamReader-Konstruktor kann wie folgt geändert werden:

 new InputStreamReader(is, Charset.forName("UTF-8")) 

Ich habe hier einen Benchmark mit 14 verschiedenen Antworten gemacht (Entschuldigung dafür, dass ich keine Credits angegeben habe, aber es gibt zu viele Duplikate)

Das Ergebnis ist sehr überraschend. Es stellt sich heraus, dass Apache IOUtils die langsamste und ByteArrayOutputStream die schnellste Lösung ist:

Also zuerst hier ist die beste Methode:

 public String inputStreamToString(InputStream inputStream) throws IOException { try(ByteArrayOutputStream result = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { result.write(buffer, 0, length); } return result.toString(UTF_8); } } 

Benchmark-Ergebnisse von 20 MB zufälligen Bytes in 20 Zyklen

Zeit in Millisekunden

  • ByteArrayOutputStreamTest: 194
  • NioStream: 198
  • Java9TransferTo: 201
  • Java9ISReadAllBytes: 205
  • BufferedInputStreamVsByteArrayOutputStream: 314
  • ApacheStringWriter2: 574
  • GuavaCharStreams: 589
  • ScannerReaderNoNextTest: 614
  • ScannerReader: 633
  • ApacheStringWriter: 1544
  • StreamApi: Fehler
  • ParallelStreamApi: Fehler
  • BufferReaderTest: Fehler
  • InputStreamAndStringBuilder: Fehler

Benchmark-Quellcode

 import com.google.common.io.CharStreams; import org.apache.commons.io.IOUtils; import java.io.*; import java.nio.ByteBuffer; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.nio.channels.WritableByteChannel; import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.stream.Collectors; /** * Created by Ilya Gazman on 2/13/18. */ public class InputStreamToString { private static final String UTF_8 = "UTF-8"; public static void main(String... args) { log("App started"); byte[] bytes = new byte[1024 * 1024]; new Random().nextBytes(bytes); log("Stream is ready\n"); try { test(bytes); } catch (IOException e) { e.printStackTrace(); } } private static void test(byte[] bytes) throws IOException { List tests = Arrays.asList( new ApacheStringWriter(), new ApacheStringWriter2(), new NioStream(), new ScannerReader(), new ScannerReaderNoNextTest(), new GuavaCharStreams(), new StreamApi(), new ParallelStreamApi(), new ByteArrayOutputStreamTest(), new BufferReaderTest(), new BufferedInputStreamVsByteArrayOutputStream(), new InputStreamAndStringBuilder(), new Java9ISTransferTo(), new Java9ISReadAllBytes() ); String solution = new String(bytes, "UTF-8"); for (Stringify test : tests) { try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) { String s = test.inputStreamToString(inputStream); if (!s.equals(solution)) { log(test.name() + ": Error"); continue; } } long startTime = System.currentTimeMillis(); for (int i = 0; i < 20; i++) { try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) { test.inputStreamToString(inputStream); } } log(test.name() + ": " + (System.currentTimeMillis() - startTime)); } } private static void log(String message) { System.out.println(message); } interface Stringify { String inputStreamToString(InputStream inputStream) throws IOException; default String name() { return this.getClass().getSimpleName(); } } static class ApacheStringWriter implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, UTF_8); return writer.toString(); } } static class ApacheStringWriter2 implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { return IOUtils.toString(inputStream, UTF_8); } } static class NioStream implements Stringify { @Override public String inputStreamToString(InputStream in) throws IOException { ReadableByteChannel channel = Channels.newChannel(in); ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 16); ByteArrayOutputStream bout = new ByteArrayOutputStream(); WritableByteChannel outChannel = Channels.newChannel(bout); while (channel.read(byteBuffer) > 0 || byteBuffer.position() > 0) { byteBuffer.flip(); //make buffer ready for write outChannel.write(byteBuffer); byteBuffer.compact(); //make buffer ready for reading } channel.close(); outChannel.close(); return bout.toString(UTF_8); } } static class ScannerReader implements Stringify { @Override public String inputStreamToString(InputStream is) throws IOException { java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; } } static class ScannerReaderNoNextTest implements Stringify { @Override public String inputStreamToString(InputStream is) throws IOException { java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); return s.next(); } } static class GuavaCharStreams implements Stringify { @Override public String inputStreamToString(InputStream is) throws IOException { return CharStreams.toString(new InputStreamReader( is, UTF_8)); } } static class StreamApi implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { return new BufferedReader(new InputStreamReader(inputStream)) .lines().collect(Collectors.joining("\n")); } } static class ParallelStreamApi implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { return new BufferedReader(new InputStreamReader(inputStream)).lines() .parallel().collect(Collectors.joining("\n")); } } static class ByteArrayOutputStreamTest implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { try(ByteArrayOutputStream result = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { result.write(buffer, 0, length); } return result.toString(UTF_8); } } } static class BufferReaderTest implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { String newLine = System.getProperty("line.separator"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder result = new StringBuilder(UTF_8); String line; boolean flag = false; while ((line = reader.readLine()) != null) { result.append(flag ? newLine : "").append(line); flag = true; } return result.toString(); } } static class BufferedInputStreamVsByteArrayOutputStream implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { BufferedInputStream bis = new BufferedInputStream(inputStream); ByteArrayOutputStream buf = new ByteArrayOutputStream(); int result = bis.read(); while (result != -1) { buf.write((byte) result); result = bis.read(); } return buf.toString(UTF_8); } } static class InputStreamAndStringBuilder implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { int ch; StringBuilder sb = new StringBuilder(UTF_8); while ((ch = inputStream.read()) != -1) sb.append((char) ch); return sb.toString(); } } static class Java9ISTransferTo implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); inputStream.transferTo(bos); return bos.toString(UTF_8); } } static class Java9ISReadAllBytes implements Stringify { @Override public String inputStreamToString(InputStream inputStream) throws IOException { return new String(inputStream.readAllBytes(), UTF_8); } } } 

Here’s more-or-less sampath’s answer, cleaned up a bit and represented as a function:

 String streamToString(InputStream in) throws IOException { StringBuilder out = new StringBuilder(); BufferedReader br = new BufferedReader(new InputStreamReader(in)); for(String line = br.readLine(); line != null; line = br.readLine()) out.append(line); br.close(); return out.toString(); } 

If you were feeling adventurous, you could mix Scala and Java and end up with this:

 scala.io.Source.fromInputStream(is).mkString("") 

Mixing Java and Scala code and libraries has it’s benefits.

See full description here: Idiomatic way to convert an InputStream to a String in Scala

If you can’t use Commons IO (FileUtils/IOUtils/CopyUtils) here’s an example using a BufferedReader to read the file line by line:

 public class StringFromFile { public static void main(String[] args) /*throws UnsupportedEncodingException*/ { InputStream is = StringFromFile.class.getResourceAsStream("file.txt"); BufferedReader br = new BufferedReader(new InputStreamReader(is/*, "UTF-8"*/)); final int CHARS_PER_PAGE = 5000; //counting spaces StringBuilder builder = new StringBuilder(CHARS_PER_PAGE); try { for(String line=br.readLine(); line!=null; line=br.readLine()) { builder.append(line); builder.append('\n'); } } catch (IOException ignore) { } String text = builder.toString(); System.out.println(text); } } 

or if you want raw speed I’d propose a variation on what Paul de Vrieze suggested (which avoids using a StringWriter (which uses a StringBuffer internally) :

 public class StringFromFileFast { public static void main(String[] args) /*throws UnsupportedEncodingException*/ { InputStream is = StringFromFileFast.class.getResourceAsStream("file.txt"); InputStreamReader input = new InputStreamReader(is/*, "UTF-8"*/); final int CHARS_PER_PAGE = 5000; //counting spaces final char[] buffer = new char[CHARS_PER_PAGE]; StringBuilder output = new StringBuilder(CHARS_PER_PAGE); try { for(int read = input.read(buffer, 0, buffer.length); read != -1; read = input.read(buffer, 0, buffer.length)) { output.append(buffer, 0, read); } } catch (IOException ignore) { } String text = output.toString(); System.out.println(text); } } 

This is an answer adapted from org.apache.commons.io.IOUtils source code , for those who want to have the apache implementation but do not want the whole library.

 private static final int BUFFER_SIZE = 4 * 1024; public static String inputStreamToString(InputStream inputStream, String charsetName) throws IOException { StringBuilder builder = new StringBuilder(); InputStreamReader reader = new InputStreamReader(inputStream, charsetName); char[] buffer = new char[BUFFER_SIZE]; int length; while ((length = reader.read(buffer)) != -1) { builder.append(buffer, 0, length); } return builder.toString(); } 

Make sure to close the streams at end if you use Stream Readers

 private String readStream(InputStream iStream) throws IOException { //build a Stream Reader, it can read char by char InputStreamReader iStreamReader = new InputStreamReader(iStream); //build a buffered Reader, so that i can read whole line at once BufferedReader bReader = new BufferedReader(iStreamReader); String line = null; StringBuilder builder = new StringBuilder(); while((line = bReader.readLine()) != null) { //Read till end builder.append(line); builder.append("\n"); // append new line to preserve lines } bReader.close(); //close all opened stuff iStreamReader.close(); //iStream.close(); //EDIT: Let the creator of the stream close it! // some readers may auto close the inner stream return builder.toString(); } 

EDIT: On JDK 7+, you can use try-with-resources construct.

 /** * Reads the stream into a string * @param iStream the input stream * @return the string read from the stream * @throws IOException when an IO error occurs */ private String readStream(InputStream iStream) throws IOException { //Buffered reader allows us to read line by line try (BufferedReader bReader = new BufferedReader(new InputStreamReader(iStream))){ StringBuilder builder = new StringBuilder(); String line; while((line = bReader.readLine()) != null) { //Read till end builder.append(line); builder.append("\n"); // append new line to preserve lines } return builder.toString(); } } 

Here is the complete method for converting InputStream into String without using any third party library. Use StringBuilder for single threaded environment otherwise use StringBuffer .

 public static String getString( InputStream is) throws IOException { int ch; StringBuilder sb = new StringBuilder(); while((ch = is.read()) != -1) sb.append((char)ch); return sb.toString(); } 

Here’s how to do it using just the JDK using byte array buffers. This is actually how the commons-io IOUtils.copy() methods all work. You can replace byte[] with char[] if you’re copying from a Reader instead of an InputStream .

 import java.io.ByteArrayOutputStream; import java.io.InputStream; ... InputStream is = .... ByteArrayOutputStream baos = new ByteArrayOutputStream(8192); byte[] buffer = new byte[8192]; int count = 0; try { while ((count = is.read(buffer)) != -1) { baos.write(buffer, 0, count); } } finally { try { is.close(); } catch (Exception ignore) { } } String charset = "UTF-8"; String inputStreamAsString = baos.toString(charset); 

Kotlin users simply do:

 println(InputStreamReader(is).readText()) 

wohingegen

 readText() 

is Kotlin standard library’s built-in extension method.

Another one, for all the Spring users:

 import java.nio.charset.StandardCharsets; import org.springframework.util.FileCopyUtils; public String convertStreamToString(InputStream is) throws IOException { return new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8); } 

The utility methods in org.springframework.util.StreamUtils are similar to the ones in FileCopyUtils , but they leave the stream open when done.

Use the java.io.InputStream.transferTo(OutputStream) supported in Java 9 and the ByteArrayOutputStream.toString(String) which takes the charset name:

 public static String gobble(InputStream in, String charsetName) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); in.transferTo(bos); return bos.toString(charsetName); } 

This one is nice because:

  • Hand safety the Charset.
  • You control the read buffer size.
  • You can provision the length of the builder and can be not exactly.
  • Is free from library dependencies.
  • Is for Java 7 or higher.

What the for?

 public static String convertStreamToString(InputStream is) { if (is == null) return null; StringBuilder sb = new StringBuilder(2048); // Define a size if you have an idea of it. char[] read = new char[128]; // Your buffer size. try (InputStreamReader ir = new InputStreamReader(is, StandardCharsets.UTF_8)) { for (int i; -1 != (i = ir.read(read)); sb.append(read, 0, i)); } catch (Throwable t) {} return sb.toString(); } 

Here’s my Java 8 based solution, which uses the new Stream API to collect all lines from an InputStream :

 public static String toString(InputStream inputStream) { BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream)); return reader.lines().collect(Collectors.joining( System.getProperty("line.separator"))); } 

The easiest way in JDK is with the following code snipplets.

 String convertToString(InputStream in){ String resource = new Scanner(in).useDelimiter("\\Z").next(); return resource; } 

Guava provides much shorter efficient autoclosing solution in case when input stream comes from classpath resource (which seems to be popular task):

 byte[] bytes = Resources.toByteArray(classLoader.getResource(path)); 

oder

 String text = Resources.toString(classLoader.getResource(path), StandardCharsets.UTF_8); 

There is also general concept of ByteSource and CharSource that gently take care of both opening and closing the stream.

So, for example, instead of explicitly opening a small file to read its contents:

 String content = Files.asCharSource(new File("robots.txt"), StandardCharsets.UTF_8).read(); byte[] data = Files.asByteSource(new File("favicon.ico")).read(); 

oder nur

 String content = Files.toString(new File("robots.txt"), StandardCharsets.UTF_8); byte[] data = Files.toByteArray(new File("favicon.ico")); 

Note: This probably isn’t a good idea. This method uses recursion:

 public String read (InputStream is) { byte next = is.read(); return next == -1 ? "" : next + read(is); // Recursive part: reads next byte recursively } 

Please don’t downvote this just because it’s a bad choice to use; this was mostly creative 🙂