BufferedReader Work Around

Discussion in 'Java' started by Jan Burse, Nov 15, 2010.

  1. Jan Burse

    Jan Burse Guest

    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
    Jan Burse, Nov 15, 2010
    #1
    1. Advertising

  2. Jan Burse

    Tom Anderson Guest

    On Mon, 15 Nov 2010, Jan Burse wrote:

    > 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

    --
    They didn't have any answers - they just wanted weed and entitlement.
    Tom Anderson, Nov 15, 2010
    #2
    1. Advertising

  3. Jan Burse

    Jan Burse Guest

    Tom Anderson schrieb:
    >
    > 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
    Jan Burse, Nov 16, 2010
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. TB
    Replies:
    2
    Views:
    3,709
  2. Peter Blatt
    Replies:
    0
    Views:
    288
    Peter Blatt
    Aug 11, 2003
  3. Robert
    Replies:
    0
    Views:
    3,046
    Robert
    Oct 5, 2003
  4. Piet
    Replies:
    0
    Views:
    508
  5. Network/Software Buyer
    Replies:
    0
    Views:
    405
    Network/Software Buyer
    May 23, 2010
Loading...

Share This Page