Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpURLConnection: what does setFixedLengthStreamingMode() want the size of?

I'm trying to upload a jpeg image buffer I got back from the Camera. I know the length, but if I pass just that length to the setFixedLengthStreamingMode() routine I get errors in the logcat telling me it expected a different size. I don't know if this is a android bug (I'm running 2.3.3 on this device), or I'm supposed to add in the sizes of headers in addition to the POST data or what. I can use setChunkedStreamingMode(0) and that works fine, but I was thinking it would be nice to avoid the overhead of copying the data. I seem to always be 155 bytes off except when I arbitrarily add in 155 bytes, then it tells me I am 2 bytes off :-).

like image 967
user1160711 Avatar asked Oct 28 '12 01:10

user1160711


1 Answers

The URLConnection buffers by default everything which is been written to its getOutputStream() in client's memory until it's closed. This is mandatory because the HTTP Content-Length response header needs to be set. But the content length is only known once all bytes have been written. This may be memory hogging when the response body is relatively large.

If you know beforehand the exact amount of bytes (note: bytes, not characters) being written, then you could use setFixedLengthStreamingMode() to set it with exactly that amount of bytes, so that the Content-Length header could be set much sooner and so that URLConnection can flush more often. In your particular case, you apparently used the wrong value.

The setChunkedStreamingMode() basically changes the transfer encoding to chunked. This is basically one line with the byte length in hexcode and then one line of written bytes therafter and then a blank line (see also wikipedia). The last line has a byte length of 0 and so the server knows when it's the end of the body so that it doesn't have to wait for any incoming data. This allows the response body being flushed more often. You should only not set it with 0, but with a sensible value, such as 1000 or so. This way every 1000 written bytes will be sent as a new chunk.

See also:

  • Using java.net.URLConnection to fire and handle HTTP requests
like image 56
BalusC Avatar answered Oct 29 '22 11:10

BalusC