Java 101: The ins and outs of standard input/output

Acquire the nuts of standard input, standard output, and standard error

In prior Java 101 articles, I referred to the concepts of redirection, standard input device, and standard output device. To demonstrate inputting data, several examples called System.in.read(). It turns out that System.in.read() inputs data from the standard input device. To demonstrate outputting information, examples chosen System.out.print() and Organisation.out.println(). In contrast to System.in.read(), those methods -- named sequences of executable code (to be explored in next month's article) -- send their output to the standard output device. Want to know more than well-nigh standard I/O concepts? Read on!

Standard I/O is a standardized input/output machinery that originates from the Unix operating system. Although this machinery is more often than not used with older non-GUI operating systems, standard I/O yet plays a office in modern GUI (graphical user interface) operating systems, where people use information technology to debug malfunctioning programs and to teach input/output in entry-level programming courses.

Equally you've probably guessed, standard I/O uses devices for inputting and outputting data. These devices include standard input, standard output, and standard error.

Standard input

The standard input device is that part of the operating arrangement that controls from where a programme receives its input. By default, the standard input device reads that input from a device commuter attached to the keyboard. However, yous can redirect, or switch, the input source to a device commuter attached to a file then that input seems to exist "magically" coming from a file -- instead of the keyboard.

A program inputs its information from the standard input device past calling Java'southward System.in.read() method. Look in the SDK documentation and you lot'll discover a course chosen Organization. That class contains a variable chosen in -- an object created from a bracket of InputStream. The period character after System states that in belongs to System, and the period character after in states that read() belongs to in. In other words, read() is a method that belongs to an object called in, which in plough belongs to a class chosen Organisation. (I will discuss more about classes, objects, and "belonging to" adjacent month.)

Arrangement.in.read() takes no arguments and returns an integer, which has led some to believe that System.in.read() returns user-entered integer numbers. To analyze, System.in.read() either returns a key's 7-fleck ASCII code (if the standard input device is gear up to the keyboard) or an eight-scrap byte from a file (if the standard input device has been redirected from the keyboard to a file). In either example, System.in.read() converts the code to a 32-chip integer and returns the result.

Assume that the standard input device is set to the keyboard. The following is a description of what happens under Windows: When you lot type a fundamental on a Windows-controlled keyboard, the operating system stores that key's 7-chip ASCII code in an internal fundamental buffer. That key buffer holds up to roughly sixteen ASCII codes and is organized every bit a beginning-in/first-out circular queue data structure. System.in.read() retrieves the ASCII code from the head of the primal buffer and then removes that code from the fundamental buffer. That 7-bit ASCII code then converts to an int -- past System.in.read() prepending 25 zero bits to the code -- and returns to the method's caller. A 2nd Organisation.in.read() method call retrieves the next ASCII code, which is at present at the head of the cardinal buffer, and then on.

Suppose in that location are no ASCII codes in the fundamental buffer. What happens? System.in.read() waits for the user to type keys and press the terminator. Under Windows, that terminator is the Enter central. Pressing Enter causes Windows to store a wagon return code (ASCII thirteen) followed past a new-line lawmaking (ASCII x) in the key buffer. Therefore, the central buffer might comprise several ASCII codes followed by a carriage render and a new-line graphic symbol. The first of those codes returns from System.in.read(). Check out that activity by keying in, compiling, and running the Echo application; its source code appears in Listing 1.

Listing 1. Echo.coffee

// Echo.java class Echo {    public static void primary (Cord [] args) throws java.io.IOException    {       int ch;       System.out.print ("Enter some text: ");       while ((ch = System.in.read ()) != '\northward')          System.out.print ((char) ch);    } }            

Repeat completes the following steps:

  1. Calls the System.out.print() method, which takes a String argument, to output a prompt
  2. Calls Organisation.in.read() to input ASCII codes from the standard input device as 32-bit integers
  3. Converts those 32-bit integers to xvi-chip Unicode characters by style of the (char) bandage
  4. Calls the System.out.print() method, which takes a char argument, to echo those Unicode characters to the standard output device

The last three steps in the previous four steps have place in a while loop, and go on until a new-line character is read. To run Echo so that information technology inputs from the keyboard and outputs to the screen, outcome the following command line: java Repeat.

Although Organisation.in.read() never throws an exception (see the word-counting topic in this article for a definition of that term), when the standard input device is set up to the keyboard, it might throw an exception when you redirect the standard input device from the keyboard to a file. For example, suppose you lot redirect the standard input device to a file, and System.in.read() reads content from the file. Now suppose that the file is situated on a floppy disk, and the user ejects that deejay during the read operation. When the ejection takes place, Organisation.in.read() throws an exception, informing the programme that information technology can't read the file. That provides the reason for appending the throws java.io.IOException clause to the main() method header. (You will explore exceptions, throwing exceptions, and related concepts in a future article.)

How do you redirect the standard input device and then that input originates from a file? The answer is to introduce a less-than sign, <, on the command line and follow that symbol with a filename. To see how that works, issue the following control line: java Echo <Repeat.java. The command line redirects the standard input device to a file called Echo.coffee. When Echo runs, considering each line ends in a new-line character, simply the first line of text in Echo.java appears on the screen.

Suppose you need a utility program that reads an entire file and either displays the file'due south contents on the screen, copies those contents to some other file, or copies those contents to a printer. Unfortunately, the Echo program but performs that task until information technology encounters the get-go new-line character. What do you practise? The answer to the problem lies in the Type application. Listing two provides the source lawmaking:

Listing 2. Type.coffee

// Blazon.java grade Type {    public static void primary (Cord [] args) throws java.io.IOException    {       int ch;       while ((ch = System.in.read ()) != -1)          System.out.print ((char) ch);    } }            

Blazon resembles Echo, however, there is no prompt, and the while loop tests against -1 (which indicates end of file) instead of \n (which indicates terminate of line). To run Type, issue the following command line: coffee Type <Type.coffee. The contents of Blazon.java -- or whatsoever file is specified -- will display. Equally an experiment, effort specifying java Type. What do you think will happen? (Hint: this plan resembles Repeat only doesn't end until y'all press Ctrl+C.)

Before, I mentioned that some programmers mistakenly recollect that System.in.read() returns a user-entered number. Equally you've just seen, that isn't the instance. But what must you do if you want to use Arrangement.in.read() to retrieve a number? Take a look at the Convert application, whose source lawmaking is presented in Listing 3.

Listing 3. Convert.java

// Convert.coffee form Convert {    public static void main (String [] args) throws java.io.IOException    {       System.out.print ("Please enter a number: ");       int num = 0;       int ch;       while ((ch = Arrangement.in.read ()) != '\n')          if (ch >= '0' && ch <= 'nine')          {              num *= 10;              num += ch - '0';          }          else              break;       System.out.println ("num = " + num);       System.out.println ("num squared = " + num * num);    } }            

Listing 3'south Catechumen programme prompts the user to enter a number (via Arrangement.out.print ("Please enter a number: ");). Information technology reads these digits -- i at a time -- and converts each digit'due south numeric code to a binary number that is added to a variable called num. Finally, calls to Arrangement.out.println() output the value within num and the square of that value to the standard output device.

Convert demonstrates the fourth dimension-honored technique of using a while loop to exam for a digit, premultiplying a variable by 10 (to make room for the incoming digit), converting a digit to its binary equivalent, and adding that binary equivalent to the variable. Nevertheless, that technique is not a sound technique to employ if you're writing a program for deployment in different countries equally some countries utilise digits other than 0 through ix -- such every bit Tamil digits. To make the program operate with other digits, you lot need to expand the if statement to test for those digits and alter the ch - '0' expression. Fortunately, Java simplifies that task by providing a Character class, which you'll explore in a futurity article.

Standard output

The standard output device is that function of the operating organisation that controls where a plan sends its output. Past default, the standard output device sends the output to a device driver attached to the screen. All the same, the output destination can be redirected to a device commuter attached to a file or printer, which results in the same program displaying its findings on the screen, saving them in a file, or providing a hardcopy listing of the results.

You achieve standard output by calling Coffee's System.out.print() and System.out.println() methods. Except for the fact that print() methods don't output a new-line character afterward the data, the two method groups are equivalent. Methods exist to output Boolean, character, character array, double-precision floating-point, floating-point, integer, long integer, string, and object values. To demonstrate these methods, Listing four presents source code to the Impress awarding.

Listing iv. Print.java

// Print.coffee grade Impress {    public static void main (Cord [] args)    {       boolean b = truthful;       System.out.println (b);       char c = 'A';       System.out.println (c);       char [] carray = { 'A', 'B', 'C' };       System.out.println (carray);       double d = three.5;       System.out.println (d);       float f = -9.3f;       Organization.out.println (f);       int i = '10';       Organization.out.println (i);       long l = 9000000;       System.out.println (l);       Cord s = "abc";       System.out.println (s);       Arrangement.out.println (new Impress ());    } }            

Listing iv has probably triggered some questions for you. First, what is all that Organisation.out. business organisation doing in front of println()? Again, refer to the Arrangement class in the SDK documentation. The form contains a variable called out -- an object created from a class called PrintStream. The catamenia character after Organisation indicates that out belongs to Organization. The menstruum graphic symbol after out states that println() belongs to out. In other words, println() is a method that belongs to an object called out, which in turn belongs to a class called Organisation.

The second question you might exist asking yourself involves println() argument information types: how is it possible for the same println() method to exist chosen with different types of statement data? The reply: because there are several println() methods in the PrintStream class. At runtime, the JVM knows which println() method to phone call by examining the number of method-call arguments and their data types. (Declaring several methods with the aforementioned name but different numbers of arguments and statement information types is known as method overloading. I will discuss that concept next month.)

Finally, you lot might be wondering near System.out.println (new Print ());. That method phone call illustrates the println() method, which takes an Object argument. First, the creation operator new creates an object from the Print class and returns a reference to -- also known as the address of -- that object. Finally, that address passes as an statement to the println() method, which takes an Object argument. The method converts the object's contents to a cord and outputs that string. By default, the string consists of the proper name of the object's grade, followed past an @ (at) character, followed by a hexadecimal-formatted integer that represents the object's hashcode. (I will present hashcodes and the conversion of objects to strings in an upcoming article.)

Compile Print.java and run the program by issuing the following command line: java Impress. You should see 9 lines of output. Redirect that output to the out.dat file by issuing the following command line: coffee Print >out.dat. You tin now view the contents of the file.

The greater-than sign, >, indicates standard output redirection. Whenever y'all desire to redirect the standard output device from the screen to a file or printer, specify that symbol followed by the file or printer name on the command line. For example, redirect Print'southward output to a Windows printer by issuing the post-obit command line: java Print >prn.