views:

349

answers:

4

When reading the InputStream of an HttpURLConnection, is there any reason to use one of the following over the other? I've seen both used in examples.

Manual Buffer:

while ((length = inputStream.read(buffer)) > 0) {
    os.write(buf, 0, ret);
}

BufferedInputStream

is = http.getInputStream();
bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);

int current = 0;
while ((current = bis.read()) != -1) {
     baf.append(current);
}

EDIT I'm still new to HTTP in general but one consideration that comes to mind is that if I am using a persistent HTTP connection, I can't just read until the input stream is empty right? In that case, wouldn't I need to read the message length and just read the input stream for that length?

And similarly, if NOT using a persistent connection, is the code I included 100% good to go in terms of reading the stream properly?

A: 

Only if you're using the BufferedInputStream-specific methods.

Delan Azabani
Further clarification added to question.
stormin986
A: 

Regarding persistent HTTP connections it is just the opposite. You should read everything from the input stream. Otherwise the Java HTTP client does not know that the HTTP request is complete and the socket connection can be reused.

See http://java.sun.com/javase/6/docs/technotes/guides/net/http-keepalive.html:

What can you do to help with Keep-Alive?

Do not abandon a connection by ignoring the response body. Doing so may results in idle TCP connections. That needs to be garbage collected when they are no longer referenced.

If getInputStream() successfully returns, read the entire response body.

Robert
A: 

I talk about a good way to do it on my blog in a post about using JSON in android. http://blog.andrewpearson.org/2010/07/android-why-to-use-json-and-how-to-use.html. I will post the relevant part of the relevant post below (the code is pretty generalizable):

InputStream in = null;
String queryResult = "";
try {
     URL url = new URL(archiveQuery);
     HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
     HttpURLConnection httpConn = (HttpURLConnection) urlConn;
     httpConn.setAllowUserInteraction(false);
     httpConn.connect();
     in = httpConn.getInputStream();
     BufferedInputStream bis = new BufferedInputStream(in);
     ByteArrayBuffer baf = new ByteArrayBuffer(50);
     int read = 0;
     int bufSize = 512;
     byte[] buffer = new byte[bufSize];
     while(true){
          read = bis.read(buffer);
          if(read==-1){
               break;
          }
          baf.append(buffer, 0, read);
     }
     queryResult = new String(baf.toByteArray());
     } catch (MalformedURLException e) {
          // DEBUG
          Log.e("DEBUG: ", e.toString());
     } catch (IOException e) {
          // DEBUG
          Log.e("DEBUG: ", e.toString());
     }
}
Andrew
There is one definite but to fix: you should always specify encoding to use for converting bytes to String (new String(baf.toByteArray(), "UTF-8").
StaxMan
A: 

Use former -- latter has no real benefits over first one, and is bit slower; reading things byte by byte is inefficient even if buffered (although horribly slow when not buffered). That style of reading input went out of vogue with C; although may be useful in cases where you need to find an end marker of some sort.

StaxMan