Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
NiceNix
Posts: 73
Registered: ‎10-23-2009
My Device: Not Specified
Accepted Solution

Problem with read(byte[], int. int) in OS 5.0.0.604

Is there a known issue with read not behaving properly in the latest versions of OS 5?

 

I have an existing app that works perfectly on all BB devices from OS 4.2.1+ ... except for the devices running the latest releases of OS 5.0.0  when I test on the simulator for OS 5.0.0.604 (generic) I get strange behaviour using the read() method on the InputStream created from an HttpConnection's InputConnection.openInputStream().  The problem only occurs when connecting using deviceside=true.  It doesn't affect MDS.  What I am seeing is:

 

read(buffer, index, length) internally fills a 1024 byte buffer with data from the http reply.

it then ignores the first 152 bytes and returns the remaining 872 into the buffer parameter.  The returned int value for number of bytes read is correct.  i.e.  872.

Subsequent calls to read() return the same 872 bytes again. ... it never advances through the stream to return the rest of the data.

Calling the available() method at any point returns the full length of the http reply (in this case 2685)

 

In all previous versions of the OS, using the same code it returns all 2685 bytes in a single call to read() ... I'm baffled.  Has anyone else seen this behaviour?

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: Problem with read(byte[], int. int) in OS 5.0.0.604

Please post the code that reproduces the issue. I presume the first 152 bytes are not HTTP response headers, correct?
Developer
NiceNix
Posts: 73
Registered: ‎10-23-2009
My Device: Not Specified

Re: Problem with read(byte[], int. int) in OS 5.0.0.604

It is possible that the first 152 bytes are response headers, that would make sense, but I would expect that the if they are,  then the return value for available() should also skip them.

 

The pertinent part of the code from my project is:

 

//DOESNT WORK - read is not advancing through the stream, it just returns bytes 152-1024 of _src._buffer repeatedly.
InputStream _src=_httpConnection.openInputStream();
int available = _src.available();
_buffer = new byte[available];

int len = _src.read(_buffer,0,available);

if (len < available)
{
	int readOffset = 0;
	while (len >= 0 && len + readOffset < available)
	{
		readOffset += len;
		len = read(_buffer, readOffset, available-readOffset);
	}
}

 

Thanks,

~NN

 

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: Problem with read(byte[], int. int) in OS 5.0.0.604

I'm not sure I can follow the logic behind this code. My suggestions:

1. Don't use InputStream.available as it is not required to return anything greater than 0 ever. See the javadocs for the contract of the method.

2. Use a simple loop that invokes InputStream.read() until it returns -1 (end of stream). For example,

_buffer = drain(_httpConnection.openInputStream());

private static byte[] drain(InputStream in) throws IOException {
  final ByteArrayOutputStream result = new ByteArrayOutputStream();
  final byte[] buf = new byte[512];
  int chunkLength;
  while ((chunkLength = in.read(buf)) != -1) {
    result.write(buf, 0, chunkLength);
  }
  result.close();
  return result.toByteArray();
}

 

 

Developer
newbie100
Posts: 105
Registered: ‎05-22-2008
My Device: Not Specified

Re: Problem with read(byte[], int. int) in OS 5.0.0.604

I have had similar issues on the 8830, but with a 4.2 or 4.5 O/s

 

Eventually I changed my read() to read a single byte at a time, rather than a buffer, and that solved

my issue.

 

 

If I remember correctly, In my case, I knew the total length, and was reading in chunks,

advancing my offset into the buffer, with the amount of data returned by read(byte[],init,int)

 

 

New Contributor
ProgrammerInParadise
Posts: 7
Registered: ‎06-03-2010
My Device: Curve, Bold, Storm

Re: Problem with read(byte[], int. int) in OS 5.0.0.604

Have you given getLength() method a try instead of available() method?

 

Quote from the doc of getLength() method:

 

"Returns the length of the content which is being provided. E.g. if the connection is via HTTP, then the value of the content-length header field is returned."

Developer
NiceNix
Posts: 73
Registered: ‎10-23-2009
My Device: Not Specified

Re: Problem with read(byte[], int. int) in OS 5.0.0.604

I was trying to use available() to figure out how big the buffer byte[] had to be.  I guess that was a bad choice.

 

I tried to replicate the odd behaviour in a sample app, but it didn't work.  I'll poke at it some more when I get some spare time and if I can consistently break it, I'll post again then.  In the meantime, I got my project working by using single byte reads and content-length.

 

Thanks for the suggestions everyone!

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: Problem with read(byte[], int. int) in OS 5.0.0.604

P.S. Keep in mind that Content-Length might not be specified, in which case you are required to read until the input stream reaches its end.