Java Input/Output  «Prev   Next»

Lesson 3Reading from the standard input
ObjectiveUse the class variable System.in. and describe an approach to reading user input.

Java System.in Read Input

When we wrote to the standard output, we used a variable that was tied to the standard output (which is, by default, the screen). This variable was the class variable System.out. Similarly, when we want to read from the standard input (which is, by default, the keyboard), we use a variable tied to the standard input. This variable is the class variable System.in. System.in refers to a variable that is a subclass of Java's InputStream class. This means we can use the methods defined by the InputStream class (in particular, the read() method) to read characters as the user types.
  • StringBuffer
    StringBuffer: If you are not familiar with the StringBuffer class, it's a class that keeps track of character data. However, unlike the String class, which is read-only (that is, once you create a String object you cannot change the characters it contains), StringBuffer is read/write. That means we can append the characters we read to the end of a StringBuffer object as we read them from the keyboard.

Here is an example of a program that reads one character at a time from the standard input. It adds each character read, one at a time, to an instance of class StringBuffer and displays the characters read at the end.


Reading from Standard Input in Java

This program keeps reading until the user presses Enter (which the program detects by looking for a new line character).
import java.io.*;

class FirstEcho {
   public static void main(String[ ] args) {
      try {
          char c;
          StringBuffer sb = new StringBuffer();
          while ((c = (char)System.in.read()) != '\n')
             sb.append( c );
          System.out.println( sb );
      } catch (IOException e) {
      }
   }
}

This stand-alone program must cast the result of read() to a char. The result of read() is actually an int representing the ASCII character read (in other words, it is in the range of 0 to 255). However, when read() reaches the end of the data, it returns the value -1. You can make this occur when entering data from the keyboard by typing Ctrl-Z. Otherwise, this will occur when reading from a file when you have reached the end. The read() method might also throw an IOException if it encountered a problem when attempting to perform the read. So, we set up the read() call within a try block and catch any IOExceptions that occur.


Java System.in Read Input Class since its Java 1.1 Inception

The `System.in` functionality in Java has largely remained the same since its inception in Java 1.1, serving as a standard input stream for reading input from the console. However, the way it is commonly used has evolved with the introduction of additional tools and classes in the Java standard library. Here’s a breakdown of changes and improvements:
Key Changes and Enhancements
  1. Java 1.1 - Core Functionality
    • The System.in stream was introduced as a low-level, byte-oriented input stream.
    • By default, it uses InputStream, requiring users to handle raw bytes or wrap it in classes like BufferedReader or Scanner for reading text input.
  2. Java 5 - Introduction of Scanner
    • The Scanner class was introduced to simplify parsing of primitive types and strings from System.in.
    • Example:
      Scanner scanner = new Scanner(System.in);
      System.out.print("Enter a number: ");
      int number = scanner.nextInt();
              
    • Scanner supports various input formats and locales, making it much easier and more flexible than prior methods.
  3. Java 8 - Stream API Integration
    • While System.in itself did not change, Java 8's Stream API made it easier to process user input as streams.
    • Example:
      BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
      reader.lines().forEach(System.out::println);
              
  4. Java 9 - Enhancements to InputStream
    • The InputStream interface gained methods like readAllBytes(), transferTo(), and readNBytes() to simplify input handling.
    • Example:
      byte[] input = System.in.readAllBytes();
      String data = new String(input);
              
  5. General Performance and Encoding Improvements
    • Modern JVMs have optimized the performance of System.in over time.
    • Handling of character encodings has also improved with the availability of classes like InputStreamReader to convert bytes to characters correctly.


Limitations that Remain Unchanged
  • Blocking Nature: System.in remains a blocking stream, which means the program will wait until input is provided.
  • Byte-Oriented: It is still fundamentally a byte stream, requiring higher-level wrappers for textual or formatted input.

Summary The core functionality of `System.in` has not changed significantly since Java 1.1, but usability has improved with new APIs like `Scanner`, Stream API enhancements, and additional methods in the InputStream class. Developers now have more tools for handling input efficiently and intuitively, though the underlying `System.in` concept has stayed consistent.

Read Standard Input - Exercise

Exercises on reading from the standard input span two lessons.
In this first exercise, you will write a a stand-alone, character-mode program that reads from the standard input into a StringBuffer object.
In the second exercise you will learn about data streams and will add them to the program you write in this exercise.

Read Standard Input - Exercise

SEMrush Software