By Johnny Maelstrom


2008-11-21 16:47:40 8 Comments

If you have a java.io.InputStream object, how should you process that object and produce a String?


Suppose I have an InputStream that contains text data, and I want to convert it to a String, so for example I can write that to a log file.

What is the easiest way to take the InputStream and convert it to a String?

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

30 comments

@Viacheslav Vedenin 2016-02-17 00:58:48

Summarize other answers I found 11 main ways to do this (see below). And I wrote some performance tests (see results below):

Ways to convert an InputStream to a String:

  1. Using IOUtils.toString (Apache Utils)

    String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
    
  2. Using CharStreams (Guava)

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

    Scanner s = new Scanner(inputStream).useDelimiter("\\A");
    String result = s.hasNext() ? s.next() : "";
    
  4. Using Stream API (Java 8). Warning: This solution converts different line breaks (like \r\n) to \n.

    String result = new BufferedReader(new InputStreamReader(inputStream))
      .lines().collect(Collectors.joining("\n"));
    
  5. Using parallel Stream API (Java 8). Warning: This solution converts different line breaks (like \r\n) to \n.

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

    final int bufferSize = 1024;
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    Reader in = new InputStreamReader(stream, StandardCharsets.UTF_8);
    int charsRead;
    while((charsRead = in.read(buffer, 0, buffer.length)) > 0) {
        out.append(buffer, 0, charsRead);
    }
    return out.toString();
    
  7. Using StringWriter and IOUtils.copy (Apache Commons)

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

    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. Using BufferedReader (JDK). Warning: This solution converts different line breaks (like \n\r) to line.separator system property (for example, in Windows to "\r\n").

    String newLine = System.getProperty("line.separator");
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder result = new StringBuilder();
    boolean flag = false;
    for (String line; (line = reader.readLine()) != null; ) {
        result.append(flag? newLine: "").append(line);
        flag = true;
    }
    return result.toString();
    
  10. Using BufferedInputStream and 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. Using inputStream.read() and StringBuilder (JDK). Warning: This solution has problems with Unicode, for example with Russian text (works correctly only with non-Unicode text)

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

Warning:

  1. Solutions 4, 5 and 9 convert different line breaks to one.

  2. Solution 11 can't work correctly with Unicode text

Performance tests

Performance tests for small String (length = 175), url in github (mode = Average Time, system = Linux, score 1,343 is the best):

              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 for big String (length = 50100), url in github (mode = Average Time, system = Linux, score 200,715 is the best):

               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

Graphs (performance tests depending on Input Stream length in Windows 7 system)
enter image description here

Performance test (Average Time) depending on Input Stream length in 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

@Tagir Valeev 2016-02-17 04:28:13

As you're writing the "summary answer", you should note that some solutions automatically convert different linebreaks (like \r\n) to \n which might be undesired in some cases. Also it would be nice to see the additional memory required or at least allocation pressure (at least you may run JMH with -prof gc). For the really cool post it would be great to see the graphs (depending on string length within the same input size and depending on the input size within the same string length).

@Aleksei Matiushkin 2016-04-15 09:17:33

Upvoted; the funniest thing is that results are more than expected: one should use standard JDK and/or Apache Commons syntactic sugar.

@mangusbrother 2016-05-07 20:20:37

Amazing post. Just one thing. Java 8 warns against using parallel streams on resources that will force you to lock and wait (such as this input stream) so the parallel stream option is rather cumbersome and not worth it no?

@Natix 2016-09-29 18:43:18

Does the parallel stream actually maintain the line ordering?

@GoGoris 2016-10-25 13:50:58

Nice comparison! I saw that IOUtils uses an InputStreamReader and StringBuilder underneath. The reason why IOUtils.toString is slower with a small string and faster with a large string in your test is probably because they use a default buffer size of 4*1024 bytes instead of 1024 bytes.

@jnr 2016-12-07 19:29:18

Nice list. Why Reader in solution #6 is not final BTW

@Rob Stewart 2017-04-13 22:12:08

What is reset() for in example 11 ?

@Felix D. 2017-04-18 21:34:58

@Natix you could use ordered() for that, AFAIK

@Duarte Meneses 2017-05-09 10:59:49

Note that this assumes that the inputStream has all bytes immediately available. That's usually not the case: typically you read from some IO interface. I'm curious if that would change the results. With networking for example, perhaps it's better to to the conversion of the bytes using the charset decoder while reading so that meanwhile the underlying protocol can buffer more data.

@yankee 2017-07-22 21:01:58

Number 6 is basically the same that spring's StreamUtils.copyToString does (but with 4K buffer which can make a big difference...)

@java-addict301 2017-07-24 21:15:16

Very nice comparison. The outcome is quite surprising to me. Are there any known util libraries that wrap #8? It would be very helpful to memory-profile these as well, but #8's footprint is going to be very small anyway.

@prayagupd 2017-11-07 22:54:09

I keep coming here and def message = new BufferedReader(new InputStreamReader(http.getInputStream())).lines().collect(Co‌​llectors.joining("")‌​) is the best invention of human kind

@TacB0sS 2017-12-19 09:35:58

@java-addict301 github.com/nu-art/nu-art-core, com.nu-art-software:nu-art-core:0.8.71 is the latest

@TomWolk 2018-05-30 10:03:05

Solution 10. BufferedInputStream, ByteArrayOutputStream is only slow because single bytes are read. With a buffer it would be as fast as Solution 8

@Andrew Henle 2018-06-28 20:18:43

And Solution 8 might be faster with a buffer larger than 1024 bytes.

@Luke Hutchison 2018-10-17 10:45:14

This is a great answer, but it is missing the new standard Java 9+ solution: String result = new String(input.readAllBytes(), StandardCharsets.UTF_8);

@Luke Hutchison 2018-10-17 10:47:05

@Natix @FelixD. you do in fact need ordered() with parallelStream() (and it will turn it into a serial stream too, or at least it only seems to use one thread at a time).

@Hisham Muneer 2018-10-19 16:46:51

@RobStewart - >> "What is reset() for in example 11 ?" - With reset() you can re-read the stream from the position you marked before, only if the given inputstream supports mark and reset. You can call markSupported() to check if marking is supported. docs.oracle.com/javase/7/docs/api/java/io/InputStream.html

@MC Emperor 2019-01-07 11:25:36

For anyone struggling to read the chart (due to four colors blue): the order from bottom to top is: 8. ByteArrayOutputStream and inputStream.read (JDK) — 7. StringWriter and IOUtils.copy (Apache Commons) — 1. IOUtils.toString (Apache Utils) — 6. InputStreamReader and StringBuilder (JDK) — 9. BufferedReader (JDK) — 4. Stream API (Java 8) — 5. parallel Stream API (Java 8) — 10. BufferedInputStream and ByteArrayOutputStream (JDK) — 3. Scanner (JDK) — 2. CharStreams (Guava) — 11. inputStream.read() and StringBuilder (JDK).

@TacB0sS 2019-04-05 15:00:01

While I appreciate the effort and really like this.. it is a summary.. the real answers are bellow!! This is one of the things that are messed up in the scoring system on SO

@yurez 2019-04-19 12:00:57

2b. new String(ByteStreams.toByteArray(inputStream), Charsets.UTF_8)

@p udaykiran 2019-11-28 16:34:01

@Viacheslav I am getting a warning Resource leak: '<unassigned Closeable value>' is never closed in eclipse when using 4th point, can you tell me how to close open buffer in java8

@user12402945 2019-11-20 12:49:24

This Code is for New Java Learners:

     private String textDataFromFile;

public String getFromFile(InputStream myInputStream) throws FileNotFoundException, IOException {

      BufferedReader bufferReader = new BufferedReader (new InputStreamReader(myInputStream));

       StringBuilder stringBuilder = new StringBuilder();

  String eachStringLine;

    while((eachStringLine=bufferReader.readLine()) != null){          
        stringBuilder.append(eachStringLine).append("\n");
    }

   textDataFromFile = stringBuilder.toString(); 



  return textDataFromFile;

}

@Tagir Valeev 2015-09-02 11:50:45

For completeness here is Java 9 solution:

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

The readAllBytes is currently in JDK 9 main codebase, so it likely to appear in the release. You can try it right now using the JDK 9 snapshot builds.

@Rekin 2015-09-03 09:22:12

Does not the method allocate a whole lot of memory for reading? byte[] buf = new byte[DEFAULT_BUFFER_SIZE]; where MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; which gives MAX_BUFFER_SIZE = 2147483639. Google says its around 2.147 GB.

@Rekin 2015-09-03 09:27:22

Sorry, I made an error in calculations. It is 2 GB. I've edited the comment. So, even If I read like a 4kb file I use 2gb of memory?

@Christian Hujer 2016-01-31 21:58:06

The method is already there in Java 8. And it only allocates DEFAULT_BUFFER_SIZE bytes which is 8192, which then is increased in powers of 2, not MAX_BUFFER_SIZE.

@Tagir Valeev 2016-02-01 07:54:46

@ChristianHujer, I don't see it in the latest jdk8u commit. AFAIK new methods are never introduced in Java updates, only in major releases.

@Christian Hujer 2016-02-02 11:36:42

Ya you have to use Path instead of InputStream, it's here: docs.oracle.com/javase/8/docs/api/java/nio/file/…

@Tagir Valeev 2016-02-02 12:02:42

@ChristianHujer, the question was about InputStream, not about Path. The InputStream can be created from many different sources, not only files.

@Christian Hujer 2016-02-02 12:06:39

Yes, you're right. And that's why I/O in Java still sucks. The attempt of making it generic is always stopped at 60-70% and methods like readAllBytes() keep on ending up in the wrong places.

@Klitos Kyriacou 2017-11-17 10:21:12

This was written a year ago, so to update, I confirm that this method is indeed in the public release JDK 9. Furthermore, if your encoding is "ISO-Latin-1" then this will be extremely efficient since Java 9 Strings now use a byte[] implementation if all characters are in the first 256 code points. This means the new String(byte[], "ISO-Latin-1") will be a simple array copy.

@13hola 2018-06-28 12:45:51

I have created this code, and it works. There are no required external plug-ins.

There is a converter String to Stream and Stream to String:

import java.io.ByteArrayInputStream;
import java.io.InputStream;

public class STRINGTOSTREAM {

    public static void main(String[] args)
    {
        String text = "Hello Bhola..!\nMy Name Is Kishan ";

        InputStream strm = new ByteArrayInputStream(text.getBytes());    // Convert String to Stream

        String data = streamTostring(strm);

        System.out.println(data);
    }

    static String streamTostring(InputStream stream)
    {
        String data = "";

        try
        {
            StringBuilder stringbuld = new StringBuilder();
            int i;
            while ((i=stream.read())!=-1)
            {
                stringbuld.append((char)i);
            }
            data = stringbuld.toString();
        }
        catch(Exception e)
        {
            data = "No data Streamed.";
        }
        return data;
    }

@TacB0sS 2012-05-08 20:24:11

This is the best pure Java solution that fits perfectly for Android and any other JVM.

This solution works amazingly well... it is simple, fast, and works on small and large streams just the same!! (see benchmark above.. No. 8)

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

@vortexwolf 2013-01-14 19:30:26

Works well on Android in comparison with other answers which work only in enterprise java.

@Adam 2013-04-15 17:18:54

Crashed in Android with OutOfMemory error on the ".write" line, every time, for short strings.

@TacB0sS 2013-08-18 10:50:07

I've added the encoding. just as a side note, the original readFully method I have in my code does not return String, it returns byte[] for a more general purpose functionality. Implementing the new String(...) with encoding is the responsibility of the on that uses the API!

@njzk2 2014-04-18 18:07:12

Quick note: The memory footprint of this is maxed by 2*n, where n is the size of the stream, as per the ByteArrayInputStream auto-growing system.

@Oliv 2015-01-22 08:33:58

Unnecessarily doubles memory usage, that is precious on mobile devices. You'd better use InputStreamReader and append to StringReader, the byte to char conversion will be done on the fly, not in bulk at the end.

@Daniel De León 2014-06-08 07:46:30

This one is nice because:

  • It safely handles the Charset.
  • You control the read buffer size.
  • You can provision the length of the builder and it doesn't have to be an exact value.
  • Is free from library dependencies.
  • Is for Java 7 or higher.

How to do it?

public static String convertStreamToString(InputStream is) throws IOException {
   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));
   }
   return sb.toString();
}

For JDK 9

public static String inputStreamString(InputStream inputStream) throws IOException {
    try (inputStream) {
        return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
    }
}

@Christian Hujer 2016-01-31 22:03:01

The catch (Throwable) shouldn't really be empty if this is production code.

@Daniel De León 2019-05-16 19:12:03

You right @ChristianHujer, thanks for the advice.

@alex 2019-06-18 14:13:01

what to put in this catch - throwable statement?

@Hasee Amarathunga 2019-03-28 08:49:36

I suggest the StringWriter class for that problem.

StringWriter wt= new StringWriter();
IOUtils.copy(inputStream, wt, encoding);
String st= wt.toString();

@HyperNeutrino 2015-11-17 03:23:02

Note: This probably isn't a good idea. This method uses recursion and thus will hit a StackOverflowError very quickly:

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 :)

@Stephen C 2019-01-16 13:33:39

It is not just a bad choice. It will fail with a StackOverflowError if the input stream contains more than a few hundred characters.

@HyperNeutrino 2019-01-16 16:30:32

@StephenC That constitutes a bad choice in my opinion

@Stephen C 2019-01-16 22:20:42

I agree. It is a "bad choice" to use a method that doesn't work (except in trivial cases). But not just a "bad choice". Anyhow, I am down voting because this is wrong ... not because it is a "bad choice". And also because you don't explain why this approach should not be used.

@HyperNeutrino 2019-01-17 15:47:00

@StephenC I don't fundamentally agree with you, but thank you for at least leaving a comment instead of just fly-by downvoting. Recursion overflow issues are system limitations, and this method is not wrong, it just causes memory issues faster (albeit MUCH faster) than other methods.

@Stephen C 2019-01-17 22:30:52

For the Java language and implementations, the absence of tail-call optimization is a deliberate design choice; see softwareengineering.stackexchange.com/questions/272061/…. It should be viewed as inherent to Java. Certainly it is common to all extant mainstream Java implementations ... including Android.

@parsecer 2019-05-13 23:28:29

I liked your method, it's highly unusual. However, I don't get why it would "cause memory issues much faster"?

@HyperNeutrino 2019-05-14 18:20:27

@parsecer because instead of running out when the RAM can't handle the memory being used, it dies when the stack can't handle more stack calls, which is a lot smaller of a number on any reasonable system.

@Ilya Gazman 2018-02-13 21:30:08

I did a benchmark upon 14 distinct answers here (sorry for not providing credits but there are too many duplicates).

The result is very surprising. It turns out that Apache IOUtils is the slowest and ByteArrayOutputStream is the fastest solutions:

So first here is the best method:

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 results, of 20 MB random bytes in 20 cycles

Time in milliseconds

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

Benchmark source code

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

}

@Dalibor 2019-05-16 22:08:04

Making benchmarks in Java is not easy (especially because of JIT). After reading Benchmark source code, I'm convinced that those values above are not precise and everyone should be careful by believing them.

@Ilya Gazman 2019-05-28 14:06:28

@Dalibor you probably should provide more reasoning for your claim rather than just a link.

@Dalibor 2019-05-29 22:04:46

I think that it is really known fact that it is not easy to make your own benchmark. For those who do not know that, there is link ;)

@Ilya Gazman 2019-05-29 23:56:47

@Dalibor I am perhaps not the best, but I have a good understanding of Java benchmarks, so unless you can point out a specific problem, you are just misleading, and I will not continue the conversation with you under those conditions.

@DavidS 2019-11-15 18:48:01

Mostly I agree with Dalibor. You say you have a "good understanding of Java benchmarks", but you seem to have implemented the most naive approach while being apparently ignorant of the well known issues of this approach. For starters, read every post on this question: stackoverflow.com/questions/504103/…

@Ilya Gazman 2019-11-15 20:59:38

@DavidS my test complies with the rules in the excepted answer that you linked. Are you able to point out for any problem in my implementation?

@DavidS 2019-11-15 21:55:56

From the accepted answer: Rule 0: Read the paper, which essentially warns against attempting a micro-benchmark. Rule 1: You have no warm up phase. Rule 2-3: You've given no indication you used these flags. Rule 8: Use a library like JMH. With 135 votes in the comments: Don't use System.currentTimeMillis(). Moving on to other highly voted answers. Jon Skeet: use System.gc() between iterations, and run your test long enough to measure the results in seconds, not milliseconds. Mixing tests in a single JVM run is bad, as the compiler optimizations done for one test will impact another.

@DavidS 2019-11-19 21:26:36

I have some free time, so here are a few more. Rule 5: You include the first iteration in your timing phase. Rule 6: You have used no special tools to "read the compilers mind". Rule 7: You have given no indication that you used these flags. There, I think that about covers it. I think that's every rule except for rule 4.

@Ilya Gazman 2019-11-20 03:36:34

@DavidS Rule 0,8: As I already mentioned, I know what I am doing, so this one does not applies here, there is more than one way to do things. Rule 1: of course I do, read my code more carefully, the test is called before the timer starts to worm up! As for System.gc(), it's just hint for for the system, you cannot trust it to do anything.

@Ilya Gazman 2019-11-20 03:38:28

@DavidS if you disagree with my implementation, run your own banchmark using what ever library you want and bring your results here. I be happy to compare

@DavidS 2019-11-20 18:02:26

You asked me to point out the problems. I have done so. I'm almost done trying to convince you, but here we go one more time. Rule 1: A single iteration is not a "warm up": the JIT compiler optimizes after thousands of iterations, not one. System.gc is a just a hint, but it's a very reliable one, and it would improve your tests. Finally, you are ignoring all of the other points: compiler flags, currentTimeMillis, splitting tests across multiple JVM runs. These are the serious problems with your attempt at benchmarking. I did not make them up myself: they are well known practices and tools.

@Ilya Gazman 2019-11-20 21:16:53

@DavidS I think you are miss reading this. Check out the input size. It's 1M byte array. Iterating on it once means the underline stream implementation is going todo a lot of loops.

@DavidS 2019-11-20 21:32:40

How many loops for warm-up? Will the loop count vary by algorithm used? Will it be enough to ensure the JIT compiler has achieved optimization? How would you know when it is enough? Wouldn't it be better to explicitly declare a warm-up phase with a known-number of iterations instead of relying on the underlying stream implementation? Wouldn't it be better to use a tool like JMH instead of trying to account for all of this?

@Ravi 2016-05-26 05:07:49

Also you can get InputStream from a specified resource path:

public static InputStream getResourceAsStream(String path)
{
    InputStream myiInputStream = ClassName.class.getResourceAsStream(path);
    if (null == myiInputStream)
    {
        mylogger.info("Can't find path = ", path);
    }

    return myiInputStream;
}

To get InputStream from a specific path:

public static URL getResource(String path)
{
    URL myURL = ClassName.class.getResource(path);
    if (null == myURL)
    {
        mylogger.info("Can't find resource path = ", path);
    }
    return myURL;
}

@Stephen C 2019-01-16 13:27:15

This does not answer the Question.

@Rys 2014-01-16 14:03:45

You can use Apache Commons.

In the IOUtils you can find the toString method with three helpful implementations.

public static String toString(InputStream input) throws IOException {
        return toString(input, Charset.defaultCharset());
}

public static String toString(InputStream input) throws IOException {
        return toString(input, Charset.defaultCharset());
}

public static String toString(InputStream input, String encoding)
            throws IOException {
        return toString(input, Charsets.toCharset(encoding));
}

@rkosegi 2018-10-03 19:13:57

What is difference between first 2 methods?

@Victor 2013-03-09 20:13:49

Well, you can program it for yourself... It's not complicated...

String Inputstream2String (InputStream is) throws IOException
    {
        final int PKG_SIZE = 1024;
        byte[] data = new byte [PKG_SIZE];
        StringBuilder buffer = new StringBuilder(PKG_SIZE * 10);
        int size;

        size = is.read(data, 0, data.length);
        while (size > 0)
        {
            String str = new String(data, 0, size);
            buffer.append(str);
            size = is.read(data, 0, data.length);
        }
        return buffer.toString();
    }

@user246645 2013-11-08 10:27:29

Since you're using buffer variable locally with no chance of being shared across multiple threads you should consider changing its type to StringBuilder, to avoid the overhead of (useless) synchronization.

@Victor 2013-11-08 16:19:44

That's a good point alex!. I thing that we both agree that this method isn't thread-safe in many ways. Even the input stream operations aren't thread-safe.

@Vlad Lifliand 2014-08-08 22:47:45

If the stream contains UTF-8 character that spans across several lines, this algorithm can cut the character in two breaking the string.

@Christian Hujer 2016-01-31 22:05:01

@VladLifliand How exactly would a UTF-8 character manage to span across several lines? That's impossible by definition. You probably meant something else.

@ᴠɪɴᴄᴇɴᴛ 2019-03-17 20:07:31

@ChristianHujer He probably means buffers instead of lines. UTF-8 codepoints/characters can be multi-byte.

@Christian Hujer 2019-03-19 08:07:43

Oh yes, they can, and most of them are, multi-byte in UTF-8. Only US-ASCII-7 is not multi-byte in UTF-8. If it's buffers, as in the code, it makes sense. Just not with lines.

@sampathpremarathna 2011-08-04 08:29:44

Use:

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();

@Paul de Vrieze 2012-04-20 18:36:54

The thing is, you're first splitting into lines, and then undoing that. It's easier and faster to just read arbitrary buffers.

@María Arias de Reyna Domínguez 2012-09-10 08:08:02

Also, readLine does not distinguish between \n and \r, so you cannot reproduce the exact stream again.

@Thufir 2013-08-28 06:52:41

@PauldeVrieze how many lines, and how quickly do you need to process them!? I would hazard a guess that any performance loss would be small, or could be handled by every once in a while logging them to a file and destroying the old String obj's.

@njzk2 2014-04-18 18:05:10

very inefficient, as readLine read character by character to look for EOL. Also, if there is no line break in the stream, this does not really make sense.

@Gibbs 2015-09-21 18:11:53

@Delawn I am not able to understand your point. Can u pls explain? Coz if new line is part of stream then It will also be added to stringbuilder. Isn't?

@Russ Bateman 2016-01-04 22:01:13

@Gops AB: If you try this out, and your sample had newlines in it, you'll see that the way this loop is constructed using readline() and StringBuilder.append() does not in fact preserve the newlines.

@Jeffrey Blattman 2016-01-18 19:16:38

This isn't the best answer because it's not strictly byte in byte out. The reader chomps newlines, so you have to be careful to maintain them.

@Raedwald 2019-01-28 13:31:53

This leaks resources if an exception is thrown.

@user207421 2019-04-23 23:18:47

@njzk2 Buffered.Reader.readLine() is,err, buffered. So it isn't 'very inefficient'.

@njzk2 2019-04-24 06:37:27

@user207421 at the time of this comment, I was looking at an implementation of bufferereader where it would literally read character by character searching for the eol character, with zero buffering. Looking at openjdk8 current implementation, it's indeed not the case

@parsecer 2019-05-14 00:02:44

@njzk2 Well, all that you'd need is to replace the readLine() with read(), right? And null with -1.

@Pavel Repin 2011-03-26 20:40:25

Here's a way using only the standard Java library (note that the stream is not closed, your mileage may vary).

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

I learned this trick from "Stupid Scanner tricks" article. The reason it works is because Scanner iterates over tokens in the stream, and in this case we separate tokens using "beginning of the input boundary" (\A), thus giving us only one token for the entire contents of the stream.

Note, if you need to be specific about the input stream's encoding, you can provide the second argument to Scanner constructor that indicates what character set to use (e.g. "UTF-8").

Hat tip goes also to Jacob, who once pointed me to the said article.

@user486646 2012-04-21 17:07:21

Thanks, for my version of this I added a finally block that closes the input stream, so the user doesn't have to since you've finished reading the input. Simplifies the caller code considerably.

@CFL_Jeff 2012-08-09 13:36:49

@PavelRepin @Patrick in my case, an empty inputStream caused a NPE during Scanner construction. I had to add if (is == null) return ""; right at the beginning of the method; I believe this answer needs to be updated to better handle null inputStreams.

@Archimedes Trajano 2013-02-28 12:13:33

The problem with this approach I find is it does not handle CR/LF translations too well. So you have to make sure your line endings are consistent.

@Pavel Repin 2013-03-01 09:18:42

@ArchimedesTrajano does IOUtils.copy(inputStream, writer, encoding) deal with CR/LF translations better? I think CR/LF consistency is entirely unrelated issue. Not saying it isn't an issue.

@earcam 2013-06-13 05:24:36

For Java 7 you can close in a try-with: try(java.util.Scanner s = new java.util.Scanner(is)) { return s.useDelimiter("\\A").hasNext() ? s.next() : ""; }

@Taig 2013-07-16 07:59:37

Unfortunately this solution seems to go and lose the exceptions thrown in my underlying stream implementation.

@isapir 2013-08-28 19:54:52

excellent trick! any ideas about performance of Scanner vs reading the stream in a more verbose way?

@Pavel Repin 2013-08-28 23:13:19

@Igal I didn't measure it. If you do, gist it and I'll append your results to the answer.

@Ryan 2014-02-24 05:36:26

FYI, hasNext blocks on console input streams (see here). (Just ran into this issue right now.) This solution works fine otherwise... just a heads up.

@Mark 2015-03-14 21:33:42

@earcam thanks for the tip! For those wondering how this works, it's thanks to try-with-resources

@Normunds Kalnberzins 2015-12-16 14:16:18

looks like a neat trick, but it seems there are some limitations. For me it hangs when reading InputStream from Socket. When testing with something like ByteArrayInputStream it works nicely. Reading from socket results in a hang.

@XenoRo 2015-12-28 14:06:22

If the Scanner is going to be "giving us only one token for the entire contents of the stream" anyways, why not use a normal stream reader? Scanneris meant to pre-parse tokens out of the stream, not for being the stream reader (without any parsing being done).

@Pavel Repin 2016-01-15 01:23:04

@AlmightyR Scanner has built-in stream reading logic and we're telling it that the stream has just one token. A special case of Scanner usage. Fair game. Good point though. This stuff is clearly a hack.

@WestFarmer 2016-04-20 10:22:03

be careful ,using this method with socket stream is slow ! Scanner#next() hangs for a little while.

@Eng. Samer T 2017-07-23 16:04:35

nice answer, the article link is on oracle website community.oracle.com/blogs/pat/2004/10/23/stupid-scanner-tri‌​cks

@Aaron Brager 2018-11-09 19:12:40

You may wish to use new java.util.Scanner(is, "UTF-8") to avoid relying on default encoding, which can vary between platforms

@user207421 2019-04-23 23:16:48

@WestFarmer It isn't slow. The input is slow arriving, and the method blocks until it does so. Any method. Nothing to do with this code.

@DJDaveMark 2010-05-18 12:57:53

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

@greuze 2012-01-24 12:27:09

In order to make your code work, I had to use this.getClass().getClassLoader().getResourceAsStream() (using Eclipse with a maven project)

@Jon Moore 2009-06-10 21:07:11

Use:

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

@user207421 2017-02-24 00:07:40

@DanielDeLeón No it doesn't. It's a BufferedInputStream. The underlying reads are 8192 bytes at a time.

@jk7 2017-03-17 23:13:46

@EJP I've found it to be slower than using the BufferedInputStream and reading into a byte array buffer instead of one byte at a time. Example: 200ms vs 60ms when reading a 4.56 MiB file.

@StaxMan 2019-01-24 06:55:44

Odd that nobody has pointed the other major problem here (yes, reading content byte-by-byte is wasteful even with buffering): it relies on whatever happens to be the "default encoding" -- this is rarely a good way. Instead, make sure to pass encoding as the argument to buf.toString().

@user207421 2019-04-23 23:21:25

@jk7 The time to read a 4.56MB file is so tiny that the differences cannot possibly have been significant.

@Chinnery 2008-12-08 20:13:42

Apache Commons allows:

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

Of course, you could choose other character encodings besides UTF-8.

Also see: (documentation)

@Guillaume Coté 2011-02-03 16:07:37

Also, there is a method that only take a inputStream argument, if you are find with the default encoding.

@Per Wiklander 2011-02-03 21:54:26

@Guillaume Coté I guess the message here is that you never should be "fine with the default encoding", since you cannot be sure of what it is, depending on the platform the java code is run on.

@Guillaume Coté 2011-02-04 15:56:01

@Per Wiklander I disagree with you. Code that is going to work on a single could be quite sure that default encoding will be fine. For code that only open local file, it is a reasonable option to ask them to be encoded in the platform default encoding.

@Chris 2012-03-09 12:04:03

To save anyone the hassle of Googling - <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-io</artifactId> <version>1.3.2</version> </dependency>

@user1018711 2014-01-13 12:35:27

Also little improvement would be to use apache io (or other) constant for character encoding instead of using plain string literal - eg: IOUtils.toString(myInputStream, Charsets.UTF_8);

@karmakaze 2015-08-02 23:55:45

Dependency groupId (for recent versions): commons-io:commons-io:2.4

@TeeTracker 2015-10-09 13:34:00

It' s a worse idea to use 3rd library to load inputstream to string. Try this gist.github.com/XinyueZ/440e015b3a1afb692812

@Krishnat Molawade 2016-09-01 05:52:45

don't we need to close inputstream object passed to IOUtils.toString(inpustream) ???

@Enoobong 2019-06-20 17:56:42

More recent dependency is <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>

@Hans Brende 2018-11-07 23:21:37

ISO-8859-1

Here is a very performant way to do this if you know your input stream's encoding is ISO-8859-1 or ASCII. It (1) avoids the unnecessary synchronization present in StringWriter's internal StringBuffer, (2) avoids the overhead of InputStreamReader, and (3) minimizes the number of times StringBuilder's internal char array must be copied.

public static String iso_8859_1(InputStream is) throws IOException {
    StringBuilder chars = new StringBuilder(Math.max(is.available(), 4096));
    byte[] buffer = new byte[4096];
    int n;
    while ((n = is.read(buffer)) != -1) {
        for (int i = 0; i < n; i++) {
            chars.append((char)(buffer[i] & 0xFF));
        }
    }
    return chars.toString();
}

UTF-8

The same general strategy may be used for a stream encoded with UTF-8:

public static String utf8(InputStream is) throws IOException {
    StringBuilder chars = new StringBuilder(Math.max(is.available(), 4096));
    byte[] buffer = new byte[4096];
    int n;
    int state = 0;
    while ((n = is.read(buffer)) != -1) {
        for (int i = 0; i < n; i++) {
            if ((state = nextStateUtf8(state, buffer[i])) >= 0) {
                chars.appendCodePoint(state);
            } else if (state == -1) { //error
                state = 0;
                chars.append('\uFFFD'); //replacement char
            }
        }
    }
    return chars.toString();
}

where the nextStateUtf8() function is defined as follows:

/**
 * Returns the next UTF-8 state given the next byte of input and the current state.
 * If the input byte is the last byte in a valid UTF-8 byte sequence,
 * the returned state will be the corresponding unicode character (in the range of 0 through 0x10FFFF).
 * Otherwise, a negative integer is returned. A state of -1 is returned whenever an
 * invalid UTF-8 byte sequence is detected.
 */
static int nextStateUtf8(int currentState, byte nextByte) {
    switch (currentState & 0xF0000000) {
        case 0:
            if ((nextByte & 0x80) == 0) { //0 trailing bytes (ASCII)
                return nextByte;
            } else if ((nextByte & 0xE0) == 0xC0) { //1 trailing byte
                if (nextByte == (byte) 0xC0 || nextByte == (byte) 0xC1) { //0xCO & 0xC1 are overlong
                    return -1;
                } else {
                    return nextByte & 0xC000001F;
                }
            } else if ((nextByte & 0xF0) == 0xE0) { //2 trailing bytes
                if (nextByte == (byte) 0xE0) { //possibly overlong
                    return nextByte & 0xA000000F;
                } else if (nextByte == (byte) 0xED) { //possibly surrogate
                    return nextByte & 0xB000000F;
                } else {
                    return nextByte & 0x9000000F;
                }
            } else if ((nextByte & 0xFC) == 0xF0) { //3 trailing bytes
                if (nextByte == (byte) 0xF0) { //possibly overlong
                    return nextByte & 0x80000007;
                } else {
                    return nextByte & 0xE0000007;
                }
            } else if (nextByte == (byte) 0xF4) { //3 trailing bytes, possibly undefined
                return nextByte & 0xD0000007;
            } else {
                return -1;
            }
        case 0xE0000000: //3rd-to-last continuation byte
            return (nextByte & 0xC0) == 0x80 ? currentState << 6 | nextByte & 0x9000003F : -1;
        case 0x80000000: //3rd-to-last continuation byte, check overlong
            return (nextByte & 0xE0) == 0xA0 || (nextByte & 0xF0) == 0x90 ? currentState << 6 | nextByte & 0x9000003F : -1;
        case 0xD0000000: //3rd-to-last continuation byte, check undefined
            return (nextByte & 0xF0) == 0x80 ? currentState << 6 | nextByte & 0x9000003F : -1;
        case 0x90000000: //2nd-to-last continuation byte
            return (nextByte & 0xC0) == 0x80 ? currentState << 6 | nextByte & 0xC000003F : -1;
        case 0xA0000000: //2nd-to-last continuation byte, check overlong
            return (nextByte & 0xE0) == 0xA0 ? currentState << 6 | nextByte & 0xC000003F : -1;
        case 0xB0000000: //2nd-to-last continuation byte, check surrogate
            return (nextByte & 0xE0) == 0x80 ? currentState << 6 | nextByte & 0xC000003F : -1;
        case 0xC0000000: //last continuation byte
            return (nextByte & 0xC0) == 0x80 ? currentState << 6 | nextByte & 0x3F : -1;
        default:
            return -1;
    }
}

Auto-Detect Encoding

If your input stream was encoded using either ASCII or ISO-8859-1 or UTF-8, but you're not sure which, we can use a similar method to the last, but with an additional encoding-detection component to auto-detect the encoding before returning the string.

public static String autoDetect(InputStream is) throws IOException {
    StringBuilder chars = new StringBuilder(Math.max(is.available(), 4096));
    byte[] buffer = new byte[4096];
    int n;
    int state = 0;
    boolean ascii = true;
    while ((n = is.read(buffer)) != -1) {
        for (int i = 0; i < n; i++) {
            if ((state = nextStateUtf8(state, buffer[i])) > 0x7F)
                ascii = false;
            chars.append((char)(buffer[i] & 0xFF));
        }
    }

    if (ascii || state < 0) { //probably not UTF-8
        return chars.toString();
    }
    //probably UTF-8
    int pos = 0;
    char[] charBuf = new char[2];
    for (int i = 0, len = chars.length(); i < len; i++) {
        if ((state = nextStateUtf8(state, (byte)chars.charAt(i))) >= 0) {
            boolean hi = Character.toChars(state, charBuf, 0) == 2;
            chars.setCharAt(pos++, charBuf[0]);
            if (hi) {
                chars.setCharAt(pos++, charBuf[1]);
            }
        }
    }
    return chars.substring(0, pos);
}

If your input stream has an encoding that is neither ISO-8859-1 nor ASCII nor UTF-8, then I defer to the other answers already present.

@libnull-dev 2016-01-21 14:28:38

In terms of reduce, and concat it can be expressed in Java 8 as:

String fromFile = new BufferedReader(new   
InputStreamReader(inputStream)).lines().reduce(String::concat).get();

@Tagir Valeev 2016-01-21 16:07:48

It will be insanely slow.

@libnull-dev 2016-01-21 16:37:20

Interesting, why? Could you elaborate?

@Tagir Valeev 2016-01-22 13:21:31

don't you know why concatenating strings in loop instead of using StringBuilder is a bad idea?

@libnull-dev 2016-01-26 18:17:48

You are right. StringBuilder might be more efficient. I'll check, but my point was to show more functional approach with immutable String.

@Snekse 2017-01-26 19:40:23

In Groovy

inputStream.getText()

@Harry Lime 2008-11-21 16:54:20

A nice way to do this is using Apache commons IOUtils to copy the InputStream into a StringWriter... something like

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

or even

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

Alternatively, you could use ByteArrayOutputStream if you don't want to mix your Streams and Writers

@Bhanu Sharma 2014-02-11 05:39:38

i found filenotfound exception while i try to read file name with "До_свидания" file name(Russian language) i try with FileInputstream but it not cable to read this filename from sdcard.

@Chris.Zou 2014-08-01 03:57:25

For android developers, seems like android does not come with IOUtils from Apache. So you might consider referring to other answers.

@James 2014-09-25 23:34:21

I work in a limited footprint environment, so the solution by @PavelRepin below using the java io/util libs makes more sense.

@Esben Skov Pedersen 2014-10-23 07:29:14

@ChristofferHammarström totally agree. Even on the same machine if you run java from cmd or from your IDE.

@Donal Fellows 2015-04-15 12:49:55

IOUtils.toString() works very nicely with the Java7 try-with-resources.

@Ronan Quillevere 2015-06-18 14:47:14

maven dependency for commons-io <dependency><groupId>commons-io</groupId><artifactId>commons‌​-io</artifactId><ver‌​sion>2.4</version> </dependency>

@AutonomousApps 2015-09-07 21:23:02

For gradle users: compile 'org.apache.commons:commons-io:1.3.2' (I'm having trouble finding the latest version; anyone?)

@TeeTracker 2015-10-09 13:32:25

It' s a worse idea to use 3rd library to load inputstream to string. Try this gist.github.com/XinyueZ/440e015b3a1afb692812

@Shubham Chaudhary 2015-11-05 11:33:20

Guava version: CharStreams.toString(new InputStreamReader(stream))

@Shadoninja 2016-03-28 03:13:11

This is an incredibly old question at this point (it was asked in 2008). It is worth your time to read through more modern answers. Some use native calls from the Java 8 library.

@codepleb 2016-04-20 13:00:11

This answer is heavily outdated and one should be able to mark it as such (sadly this is not possible atm).

@Ilya Gazman 2018-02-13 21:33:08

It turns out that this method is the slowest! Check out my benchmarks here

@Steve Chambers 2018-02-25 20:52:06

In case it helps anyone I've filled in the small gap in the second part of this answer on how to close the stream in this answer.

@Roshan 2019-02-15 16:08:42

IOUtils.toString() has long been deprecated. This answer definitely is not the recommended way any more.

@Jean-François Fabre 2019-04-03 20:23:31

then edit it to explain why it is deprecated to help future readers.

@drakeet 2018-04-07 12:53:23

With Okio:

String result = Okio.buffer(Okio.source(inputStream)).readUtf8();

@Steve Chambers 2015-12-24 11:08:53

Based on the second part of the accepted Apache Commons answer but with the small gap filled in for always closing the stream:

    String theString;
    try {
        theString = IOUtils.toString(inputStream, encoding);
    } finally {
        IOUtils.closeQuietly(inputStream);
    }

@Ilya Gazman 2018-04-05 14:57:02

Note that this solution is the most inefficient based on my benchmark results

@jmehrens 2016-01-28 15:55:21

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

@virsha 2017-12-21 12:25:38

What did you passed for charset name in your case ?

@jmehrens 2017-12-21 14:54:53

@virsha You have to determine that from the source that provided the InputStream. Remember that it does not make sense to have a string without knowing what encoding it uses.

@gil.fernandes 2017-10-21 09:46:13

This solution to this question is not the simplest, but since NIO streams and channels have not been mentioned, here goes a version which uses NIO channels and a ByteBuffer to convert a stream into a string.

public static String streamToStringChannel(InputStream in, String encoding, int bufSize) throws IOException {
    ReadableByteChannel channel = Channels.newChannel(in);
    ByteBuffer byteBuffer = ByteBuffer.allocate(bufSize);
    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(encoding);
}

Here is an example how to use it:

try (InputStream in = new FileInputStream("/tmp/large_file.xml")) {
    String x = streamToStringChannel(in, "UTF-8", 1);
    System.out.println(x);
}

The performance of this method should be good for large files.

@Brett Holt 2011-10-12 17:23:01

I ran some timing tests because time matters, always.

I attempted to get the response into a String 3 different ways. (shown below)
I left out try/catch blocks for the sake readability.

To give context, this is the preceding code for all 3 approaches:

   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();

So, after running 500 tests on each approach with the same request/response data, here are the numbers. Once again, these are my findings and your findings may not be exactly the same, but I wrote this to give some indication to others of the efficiency differences of these approaches.

Ranks:
Approach #1
Approach #3 - 2.6% slower than #1
Approach #2 - 4.3% slower than #1

Any of these approaches is an appropriate solution for grabbing a response and creating a String from it.

@LukeSolar 2011-10-21 13:32:39

2) contains an error, it adds always "null" at the end of the string as you are always makeing one more step then necessary. Performance will be the same anyway I think. This should work: String read = null; StringBuffer sb = new StringBuffer(); while((read = br.readLine()) != null) { sb.append(read); }

@jk7 2017-02-24 21:29:51

It should be noted that GetMethod is a part of org.apache.commons.httpclient, not standard Java

@Ninja 2017-12-24 12:22:53

Approach #2 will consume the '\n' if the file has many lines, this should not be the answer

@yegor256 2017-08-06 18:08:30

You can use Cactoos:

String text = new TextOf(inputStream).asString();

UTF-8 encoding is the default one. If you need another one:

String text = new TextOf(inputStream, "UTF-16").asString();

@James 2016-07-29 20:58:25

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.

@Halfacht 2017-05-10 11:38:07

Raghu K Nair Was the only one using a scanner. The code I use is a little different:

String convertToString(InputStream in){
    Scanner scanner = new Scanner(in)
    scanner.useDelimiter("\\A");

    boolean hasInput = scanner.hasNext();
    if (hasInput) {
        return scanner.next();
    } else {
        return null;
    }

}

About Delimiters: How do I use a delimiter in Java Scanner?

@Thamme Gowda 2012-11-17 12:39:05

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

@Christian Hujer 2016-01-31 22:01:32

You're right about closing streams, however, the responsibility for closing streams is usually with the stream constructor (finish what you start). So, iStream should really rather be closed by the caller because the caller created iStream. Besides, closing streams should be done in a finally block, or even better in a Java 7 try-with-resources statement. In your code, when readLine() throws IOException, or builder.append() throws OutOfMemoryError, the streams would stay open.

Related Questions

Sponsored Content

85 Answered Questions

[SOLVED] How do I make the first letter of a string uppercase in JavaScript?

86 Answered Questions

[SOLVED] Is Java "pass-by-reference" or "pass-by-value"?

42 Answered Questions

[SOLVED] How do I convert a String to an int in Java?

59 Answered Questions

[SOLVED] How to replace all occurrences of a string?

65 Answered Questions

[SOLVED] What is the difference between String and string in C#?

3 Answered Questions

10 Answered Questions

[SOLVED] Does Python have a string 'contains' substring method?

34 Answered Questions

[SOLVED] How to split a string in Java

  • 2010-08-14 03:01:53
  • riyana
  • 3739392 View
  • 1565 Score
  • 34 Answer
  • Tags:   java string

16 Answered Questions

[SOLVED] Why is char[] preferred over String for passwords?

Sponsored Content