Sunday, November 05, 2006

How to convert an InputStream to a String and Back

There are four methods listed below to convert InputStream to String and String to an InputStream.
package com.bluelotussoftware.io;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
/**
*
* @author John Yeary <jyeary@bluelotussoftware.com>
* @version 2.0.0
*/
public class IOUtils {
/**
* This reads an {@link InputStream} and converts it to a {@link String}.
*
* @param is The stream to convert.
* @return The converted {@link InputStream} to text.
* @since 1.0.0
*/
public String parseISToString(InputStream is) {
DataInputStream din = new DataInputStream(is);
StringBuilder sb = new StringBuilder();
try {
String line = null;
while ((line = din.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException ex) {
ex.printStackTrace(System.err);
} finally {
try {
is.close();
} catch (IOException ex) {
}
}
return sb.toString();
}
/**
* Converts a {@link String} into an {@link InputStream}
*
* @param text The text to convert to an {@link InputStream}.
* @return An {@link InputStream} from the text value provided.
* @since 1.0.0
*/
public InputStream parseStringToIS(String text) {
if (text == null) {
return null;
}
text = text.trim();
java.io.InputStream in = null;
try {
in = new ByteArrayInputStream(text.getBytes("UTF-8"));
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace(System.err);
}
return in;
}
/**
* This reads an {@link InputStream} and converts it to a {@link String}.
*
* @param is The stream to convert.
* @return The converted {@link InputStream} to UTF-8 text.
* @since 2.0.0
*/
public String toString(final InputStream is) {
StringBuilder sb = new StringBuilder();
try (DataInputStream din = new DataInputStream(is)) {
String line;
while ((line = din.readUTF()) != null) {
sb.append(line);
}
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
return sb.toString();
}
/**
* Converts a {@link String} into an {@link InputStream}
*
* @param text The text to convert to an {@link InputStream}.
* @return A UTF-8 encoded {@link InputStream} from the text value provided.
* @since 2.0.0
*/
public InputStream toInputStream(final String text) {
if (text == null || text.isEmpty()) {
return null;
}
try (InputStream in = new ByteArrayInputStream(text.getBytes("UTF-8"))) {
return in;
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace(System.err);
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
return null;
}
}
view raw IOUtils.java hosted with ❤ by GitHub

12 comments :

Unknown said...

Well, it isn't working...I am using sockets and is I try to use this I get a Connection CLose exception.

John Yeary said...

I can not guess at what you may have encountered. This code does work. It would help if you posted a code snippet to show where its broken. Using sockets can cause a number of issues which are not necessarily related to converting an InputStream to a String, or vice-versa.

Bajal said...

Just a word of Thanks!
This works perfect for me. You saved me at least 3 hours :)

John Yeary said...

I am glad that worked for you. It is validation that the code posted does work.

Neil said...

The input stream => string conversion code isn't quite right: if the last line of the file doesn't end with a newline, the resulting String won't accurately represent the contents of the file.

Fundamentally, StringReader.readLine() is an ugly API.

John Yeary said...

Although, you may find the API "ugly", it still will accomplish the job most of the time. There are other methods available, if this does not meet your needs.

Craig Sumner said...

Thanks for the help!

Bajal said...

Hi, My code is this:
File file = new File ( "C:/File.txt" ) ;
boolean isFile = file.exists () ;
InputStream is = new FileInputStream(file) ;
String s = parseISToString(is);
System.out.println("Hi :" + s);

System.out.println("Hi :"+parseISToString(parseStringToIS(s)));

Basically, parseISToString is on client side and parseStringtoIS is on server side. I do this because InputStream is not serializable and cannot be send across EJB layer.
But my customer says he sees weird characters on screen when he includes "Kanji" chinese characters in comments.
The outputs of the above two system outs are different when the text file has chinese characters. What does that mean?

John Yeary said...

I imagine the issue has to do with the fact that the encoding is UTF-8. Since Chinese requires multi-byte to display its glyphs, you will need to use a different encoding. Try using a different encoding like UTF-16.

Anna said...

Just to add my thanks - very useful!

Unknown said...

// A much easier approach

InputStream iFile = /* get your InputStream here */

String s = "";
try{
while(true){
int x = iFile.read();
// returns -1 at the end of the stream
if(x == -1)
break;
s = s + (char)x;
}
} catch(Exception e){
e.printStackTrace();
}

John Yeary said...

Here is a longer example, but I think it is safer than using char conversions.

String s = "Hello World!";
byte[] buf = s.getBytes();
ByteArrayInputStream bais = new ByteArrayInputStream(buf);
InputStreamReader isr = new InputStreamReader(bais);
BufferedReader br = new BufferedReader(isr);
CharBuffer cb = CharBuffer.allocate(1024);
br.read(cb);
cb.flip();
System.out.println(cb.toString());

Popular Posts