BufferedReader Work Around

J

Jan Burse

Dear All

I just notice that there are different buffered reader implementations
around. I am using the int read() method of a BufferedReader instance.

The read() method invokes a fill() method, which will in turn invoke
int read(char[],int,int) of the underlying stream.

The problem arises when the underlying stream returns 0 in the
read(char[],int,int). The harmony implementation does not block:

163 int count = in.read(buf, pos, buf.length - pos);
164 if (count != -1) {
165 end += count;
166 }
http://www.docjar.com/html/api/java/io/BufferedReader.java.html

And together with the logic in read() this will give a random
return value. Which is not good.

Whereby the oracle implementation does block (JDK1.6.0_22), which
is also not good:

134 int n;
135 do {
136 n = in.read(cb, dst, cb.length - dst);
137 } while (n == 0);
138 if (n > 0) {
139 nChars = dst + n;
140 nextChar = dst;
141 }

Is there any way to obtain a buffered reader, so that in both the
harmony implementation and the oracle implementation, read() would
simply return -1?

Bye
 
T

Tom Anderson

I just notice that there are different buffered reader implementations
around. I am using the int read() method of a BufferedReader instance.

The read() method invokes a fill() method, which will in turn invoke
int read(char[],int,int) of the underlying stream.

The problem arises when the underlying stream returns 0 in the
read(char[],int,int).

I assume that by 'stream' you mean 'reader' here, rather than that you're
talking about a situation involving an InputStreamReader.

The documentation for Reader.read(char[], int, int) says:

This method will block until some input is available, an I/O error
occurs, or the end of the stream is reached.

And:

Returns: The number of characters read, or -1 if the end of the stream
has been reached

It's not clear what happens if len is 0 (InputStream returns 0 in that
situation), but as long as it isn't, this method is not allowed to return
0.

Thus, to some extent, the behaviour of the implementations when that
method returns 0 is immaterial (as long as they never try to read 0 bytes;
i haven't checked that they don't, but i am going to go out on a limb and
assume it), because that situation will not arise.

The extent to which that is not the case is the extent to which underlying
streams break the InputStream contract. But i would suggest that if you
are in that situation, the best thing to do might be to wrap the offending
stream in a filter which ensures compliance; it would detect 0 returns
from read, and either call it again, or throw an exception.
The harmony implementation does not block:

163 int count = in.read(buf, pos, buf.length - pos);
164 if (count != -1) {
165 end += count;
166 }
http://www.docjar.com/html/api/java/io/BufferedReader.java.html

Note that that fragment only runs if there is a mark in the stream; if
there's no mark, the method returns on line 142, without updating any
state. However, if it got 0 from the underlying read, then the outcome is
exactly the same as if it passed through the code you show. Which, as you
say, ...
And together with the logic in read() this will give a random return
value. Which is not good.

.... is not ideal.
Whereby the oracle implementation does block (JDK1.6.0_22), which
is also not good:

134 int n;
135 do {
136 n = in.read(cb, dst, cb.length - dst);
137 } while (n == 0);
138 if (n > 0) {
139 nChars = dst + n;
140 nextChar = dst;
141 }

It's better, because it's defined behaviour that doesn't feed you junk.
I'd marginally prefer it blew up.
Is there any way to obtain a buffered reader, so that in both the
harmony implementation and the oracle implementation, read() would
simply return -1?

Hopefully not, because that would be the wrong behaviour. -1 means end of
stream, and 0 doesn't.

But if that's really what you want, then you could use the underfilter
approach i mention above, and translate 0 into -1. The BufferedReader
should see the -1 and return a -1 of its own.

tom
 
J

Jan Burse

Tom said:
But if that's really what you want, then you could use the underfilter
approach i mention above, and translate 0 into -1. The BufferedReader
should see the -1 and return a -1 of its own.

Yeah, that is actually what I am doing now, my custom
reader, where I piggypack a buffered reader, is now
returning -1 instead of 0.

Bye
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,743
Latest member
WoodrowMea

Latest Threads

Top