Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BufferedReader doesn't return

Tags:

java

stream

I was given a task to create a java method which reads and returns the first line from the console without invoking System.in.read(byte[]) or System.in.read(byte[],int,int). (The System.in has been modified to throw an IOException if they are called.)

I came up with this solution:

InputStream a = new InputStream(){
    public int read() throws IOException{
        return System.in.read();
    }
};
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(a));
return consoleReader.readLine();

No matter what I write into the console the consoleReader.readLine() method never returns! How can I fix this?

Edit: I must use whatever InputStream System.in has been set to.

like image 227
Gergely Avatar asked Aug 26 '26 13:08

Gergely


1 Answers

The approach of creating a custom InputStream which only implements int read() is going into the right direction, unfortunately, the inherited int read(byte[] b, int off, int len), which is eventually invoked for BufferedReader.readLine is trying to fill the entire buffer, unless the end of stream has been reached.

Therefore, you have to override this method as well, allowing earlier return if there are no more bytes available:

InputStream a = new InputStream(){
    @Override
    public int read() throws IOException {
        return System.in.read();
    }
    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int r=0;
        do {
            int x=read();
            if(x<0) return r==0? -1: r;
            b[off++]=(byte)x;
            r++;
        } while(r<len && System.in.available()>0);
        return r;
    }
};
BufferedReader reader = new BufferedReader(new InputStreamReader(a));
return reader.readLine();

Note that this follows the convention of reading at least one character in every read operation (unless end of stream has been reached). This is what the other I/O classes expect and BufferedReader will call read again, if no complete line has been read yet.

like image 166
Holger Avatar answered Aug 29 '26 03:08

Holger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!