0

A related question is this one: Where is the specification that defines this behavior for InputStreamReader?, but I'm not sure if it answers mine... Please note, I'm just experimenting with the language. I have this code:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Capitalize {

    public static void main(String[] args) {

        try (BufferedReader br = new BufferedReader(new InputStreamReader(
                System.in))) {

            char c;
            do {
                c = Character.toUpperCase((char) br.read());
                System.out.print(c);
            } while (c != (char) -1);
        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
    }

}

Using ubuntu linux, I was expecting the output to be like this:

fFoOoO  bBaArR

but instead, it's like this:

foo bar (line feed)
FOO BAR (waits for more characters or Ctrl + D)

Right now I'm not sure about what is the behavior in windows, probably it's different, but still, this confuses me a bit. Reading the documentation for the read method, I see it will only return -1 if the end of stream is reached. I kind of understand how that would work for reading a file, but how about, in this case, the console? Why does it have to wait until the Ctrl + D is typed? Is there any way to get to the end of the stream without having to type Ctrl + D? Is there a way to achieve what I was expecting?

Thanks in advance

4
  • 3
    It is System.in that is line-buffered here. It has nothing to do with BufferedReader or InputStreamReader. If you want a character at a time use java.io.Console. Your question about 'get[ting] to the end of the stream without having to type Ctrl+D' is meaningless. Ctrl+D is the end of the stream. Commented Aug 20, 2014 at 1:09
  • The java.io.Console class is line buffered as well, read the Java docs. Commented Aug 20, 2014 at 1:21
  • Ok so that explains why do I get that output, the buffering independently of if BufferedReader is used. Thank you guys Commented Aug 20, 2014 at 1:26
  • @markspace Err oops my bad, tks. Commented Aug 20, 2014 at 1:36

1 Answer 1

2
  1. As EJP comments, this is nothing to do with InputStream / BufferedReader. What you are seeing is the behaviour of the Linux "tty" input drivers and a typical console command.

  2. What you are seeing is normal "line editing" or "line buffering". The input is only made available for Java to read (via the stdin file descriptor) when you press the <Enter> key. The output you are seeing prior to that is the character echoing from the "tty" drivers. (And notice that if you enter <Backspace> or whatever ... the characters get erased. When you type <Enter>, Java doesn't see the backspaces, etc. They have been edited out.)

  3. Input via the java.io.Console class behaves the same way.

  4. This is the same on Windows: the behaviour is portable. (This is a good thing ...)

  5. If you want your Java application to see the characters as they are typed, when they are typed, you will need to use 3rd-party libraries (or native code) to implement this. (In Linux, it entails switching the tty driver into "raw" mode ... and this functionality is non-portable, and not supported by standard Java SE.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.