views:

32501

answers:

8

If you have 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 this to a String (for example, so I can write the contents of the stream to a log file).

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

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

This is a very easy question, so easy that a quick google would helped you fast, here one snippet of first hits:

 BufferedInputStream ib = new BufferedInputStream(is,1024*1024);
 StringBuffer sb = new StringBuffer();
 String temp = ib.readLine();
 while (temp !=null){
     sb.append (temp);
     sb.append ("\n");
     temp = ib.readLine();
    }
 s = sb.toString()

(already optimized with Stringbuffer)

flolo
Sorry to nitpick, but I think this is using BufferedReader, not InputStream.
Harry Lime
You are right, first line got lost while copy and pasted, added it.
flolo
It's also changing the original data - it's normalising line endings to \n. That *may* be what's desired, but I'd normally start with a solution which doesn't do this.
Jon Skeet
Still not quite right - new BufferedReader(new InputStreamReader(is), buff-size)). BufferedInputStream doesn't have a 'readline'
Ken Gentle
Yes, this is easy, but the point of StackOverflow, I thought, was to be a comprehensive resource. If it's not answered already (which it wasn't), we must ask the question so that it is answered. Without prejudice ;-).
Johnny Maelstrom
+37  A: 

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);
String theString = writer.toString();

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

Harry Lime
I hope IOUtils takes an optional Charset (or at least the name of the encodding to use). Best not to leave this kind of thing to chance :)
Jon Skeet
Haha - of course it does! http://commons.apache.org/io/apidocs/org/apache/commons/io/IOUtils.html#copy(java.io.InputStream,%20java.io.Writer,%20java.lang.String)
Harry Lime
IOUtils. Great suggestion. Thanks for this.
Johnny Maelstrom
Why copy the inputstream to a writer? Why not just use a reader? Or read all bytes and use new String(bytes, charset)?
Bart van Heukelom
+12  A: 

Taking into account file one should first get a java.io.Reader instance. This can then be read and added to a StringBuilder (we don't need StringBuffer if we are not accessing it in multiple threads, and StringBuilder is faster). The trick here is that we work in blocks, and as such don't need other buffering streams. The block now is 64k, but it could be increased in size for a bit of performance gain.

final char[] buffer = new char[0x10000];
StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(is, "UTF-8");
int read;
do {
  read = in.read(buffer, 0, buffer.length);
  if (read>0) {
    out.append(buffer, 0, read);
  }
} while (read>=0);
Paul de Vrieze
Missing curly brackets before 'while'.
Arne Evertsson
+11  A: 

How about

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

?

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

Also see: http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html#toString(java.io.InputStream,%20java.lang.String)

Chinnery
IOUtils.toString is deprecated
landon9720
+3  A: 

How about:

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();
}
Jon Moore
+1  A: 

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);
    }
}
DJDaveMark
+2  A: 

If you are using Google-Collections/Guava you could do the following:

InputStream stream = ...
String content = CharStreams.toString(new InputStreamReader(p.getInputStream());
Sakuraba
+1 for suggesting Guava way. -1 because where does the variable named "stream" come in, and what is the variable 'p'?
harschware
+1  A: 

First ,you have to know the encoding of string that you want to convert.Because the java.io.InputStream operates an underlying array of bytes,however,a string is composed by a array of character that needs an encoding, e,g. UTF-8,the JDK will take the default encoding that is taken from System.getProperty("file.encoding","UTF-8");

byte[] bytes=new byte[inputStream.available()];
inputStream.read(bytes);
String s = new String(bytes);

If inputStream's byte array is very big, you could do it in loop.

:EOF

Mercy