Input is any information that is needed by your program to complete its execution. There are many forms that program input may take. Some programs use graphical components like a JOptionPane or an InputBox to accept information from the user. You are certainly familiar with programs that are controlled simply by clicking a mouse button when the mouse's cursor is in a specific area of the screen, and via pen input devices. Still other programs, like word processing programs, get some of their input from a file that is stored on one of the computer's hard drives, or an external device such as a USB drive. Some programs, like web browsers, get their data from the Internet via a network connection, while others get data from devices like scanners, digital cameras and microphones. The possibilities are limited only by computer scientists' imagination.
Output is any information that the program must convey to the user. The information you see on your computer screen is being output by one or more programs that are currently running on your computer. When you decide to print a document, a program is told to send some output to the printer. Any sound that your computer makes is because some program sent output to the speakers on your computer. The possibilities for program output are also limited only by our imagination and skills.
Throughout the semester, we will be performing input and output through the use of several of the classes in the Java Standard Edition API (currently JDK 8). We will limit our discussion to only a few classes and forms of I/O for simplicity. You may wonder why there are so many standard Java
classes for input and output. The answer is flexibility. Standard Java classes are designed to be very flexible to support the wide variety of input and output options available now and in the future. This flexibility comes at the cost of some increased complexity.
Regarding user input error handling:
In general, if a user enters letters when a program is expecting numbers, an exception [error] will occur. Such exceptions must be understood and handled by the programmer so that the program will not crash due to a simple typing error. However, there are times when that type of user input validation is not the core focus of our assignment. In those cases, we will not necessarily specify exactly what error message is to be displayed for each of the many types of errors. If we don't state the error message, it likely that is not a case we intend to test. Ask if you are unsure.
Students are asked not to change prompts or output formats unless directed by the assignment. In our time of large scale program grading, we must make use of programs to compile and run your code via test suites and other automated tools. For such programs to recognize a correct answer, the output produced by your program must match exactly the sequence and format of output we are expecting. We typically provide samples runs to ensure that you know exactly what we are expecting from your program.
The console window is the window panel that is automatically brought to the focus when you run a program that displays output from within Eclipse. Most programming languages have the ability to display a string of characters to this window on the screen or to some other standard display device.
We call this console output because the string of characters is sent out (from your program) and it appears in a console window. The System.out object is an instance of the PrintStream class, which is a type of Stream and it is this class that we will use to display standard output while the program is running. This is an important output option, since many programs that we write will produce text output to be used as input to another program. There is very little to know to use this form of output in Java. Just concatenate the values and strings you wish to display to the user. The System class is part of the java.lang package and does not need to be imported. Here is an example of sending output to the console window.
for ( int i = 0; i < 10 ; i++ ) System.out.println("The cube i^3 of " + i + " is " + (int)(Math.pow(i,2)) );
Another common use for console output is to display a prompt the user for input. Leave a space after the prompt if you chose to have the user enter their answer on the same line as the prompt (as this example demonstrate). Here is an example of prompting the user. The next section will describe user input options.
// Prompt the user for some type of information System.out.print( "What is your name? " ); // code to read (scan and save) user input would be here
An alternative output technique uses graphic user interface (GUI) objects to display text and other graphic output. The design and coding of GUI is beyond the scope of this document.
Console output in Java is very easy because the print and println methods will work with any type of data. There is a separate version of each of these methods in the PrintStream class so that this is possible. There is also a version of the print and println methods that will print information for any object. But, how did we get the PrintStream object in the first place?
The java.lang.System class creates three different I/O streams automatically for us when our application begins execution. Each of these streams is public
and
static
so that we can access them directly without having to create an instance of the System class. We will describe the InputStream object named System.in
in the discussion on console input. The other two stream objects are named System.out
and System.err.
Each of these objects is an instance of the PrintStream class and is
available for use in displaying information to the computer screen.
For example, if the following variables are defined,
int x = 3; double rate = 5.5; boolean playing = true; String phrase = "The winner is ";
they can all be displayed to the console using print or println as follows:
System.out.print( "x = " + x + " rate = " ); System.out.println( rate ); System.out.println( "playing = " + playing ); System.out.println( phrase + "Deb" );
We can also print other types of data, including other objects, using the print and println methods. The following code fragment shows the command syntax for printing a Wanderer object. The class name Wanderer is used as an example. You can replace Wanderer with any class name that is defined in your program.
Wanderer wanderer = new Wanderer( "Wilma", Color.orange );
System.out.println( wanderer );
In this case, the program prints out some cryptic information about the Wanderer object. It is the class name, an @
symbol and the hexidecimal representation of the hashcode. The output looks like the following for the Wanderer
object created.
Wanderer@13fac
Each object created (instantiated or constructed) has its own hashcode that can be used to distinguish it from other objects. However, hashcodes are not very readable for most users, so there is a way for the programmer to redefine or override what information is printed when an object reference is sent to the print or println method.
The information that is displayed when an object is printed using the print method is defined by an instance method named toString(). Every class already has a toString method already defined that returns the information as described above. All classes inherit the toString method from the java.lang.Object
class.
To redefine the toString method, you override the default version by defining a method with the same visibility and method signature as the inherited version of the method. The toString method of the Wanderer class can be overridden as follows:
/** * Returns a string representing this instance of the Wanderer class. * Example: Wilma is at (3,4) */ public String toString() { String coords = "(" + myLoc.getX() + "," + myLoc.getY() + ")"; return myName + " is at " + coords; }
Now, when the print or println method is used to print a Wanderer object, the new version of the toString method will be called instead of the version defined in the Object class. The String that is printed by the System.out.println(wanderer) method call will look something like this:
Wilma is at (11,3)
Each Java class can and should override the toString method to return a String of characters that is more descriptive of the object than the default version provided by the Object class. This method can be called by any method that needs a String that describes the object.
The print or println methods of the PrintStream class should be adequate to produce most screen output you need. Another type of output we will cover in this course is file output. Other output types require more
specialized output objects and won't be covered in this course.
Streams
A Stream
object is used to store information needed to connect a computer program to an input or output device. There is a Reader
object that adds functionality to input streams and a Printer
object that adds functionality to output streams. The PrintStream
class extends the Printer class and contains definitions for all of the versions of the print and println methods that we use to display information like user prompts or results of calculations, etc.
Because Streams can be tedious and error prone to use. The Standard Edition of Java now contains two classes to make reading input streams and sending output to output streams even more convenient. We will use java.util.Scanner
for reading characters typed by the user on the keyboard, and we will use java.io.PrintWriter
to write text information produces by our program to a file on the hard drive or other external data storage.
Console (Keyboard) Input
Programs that require the user to input information while the program is running, must prompt the user for that information in some manner. Note: The user will only know what information to type, if the program prompts (asks for) and describes the information that is required. (See Console Output for more information on output and an example user prompt.)
After the prompt is displayed, the program will wait for the user to finish typing and press Enter. When a program is waiting for input at the console, there is sometimes a blinking cursor in the console window indicating that the user should type some information. But, this is not always the case. Console input is string of characters that are entered by typing on the keyboard while the program is running and waiting for user input. Whatever the user typed is saved in an input stream and is available to the program by request in the form of a String object. We may also learn and use specialized methods to parse (interpret) the string of characters as an int or a double value.
Ever since Java 5, keyboard input and user input in general has been much better for the begining programmer. Where it used to require the use of several of the Java I/O classes, we now can focus on one type (and a few exception classes).
java.util.Scanner - connects program to an input stream and provides functionality (methods) to return data from the input stream in the form of text strings, int
values, and double
values.
We will use the System.in
object to create an instance of the Scanner class and then use that scanner object to get the user's typed input.
System.in
. System.in
, or input to your program may not be read in the order it was typed. Place your scanner at start of main method and pass it to other methods as needed or declare it to be a static data member.// In a method somewhere... // 1. Create an class member in your main program class Scanner stdin = new Scanner( System.in ); // 2. Prompt the user System.out.print( "What is your name? " ); // 3. Use the Scanner to get a line of text from the user. String name = stdin.nextLine(); // 4. Now, you can do anything with the input string that you need to. // Like, output it to the user. System.out.println( "Hi " + name + "! Welcome to my Super Duper Program" );
// 5. Once, you are done reading ALL input, close the Scanner
stdin.close();
Did you import the java.util.Scanner
class? The Scanner (and other I/O classes) is not in the standard java.lang
package. You must import Scanner
from the java.util
package.
import java.util.*; // needed for Scanner, Random, ArrayList, etc /** A Java program that demonstrates console based input and output. */ public class MyConsoleIO { // Create a single shared Scanner for keyboard input private static Scanner stdin = new Scanner( System.in ); // Program execution starts here public static void main ( String [] args ) { // Prompt the user System.out.print( "What is your name? " ); // Read a line of text from the user. String line = stdin.nextLine(); // Display the input back to the user. System.out.println( "Hello " + name ); } // end main method } // end MyConsoleIO class
Getting data from the user isn't so hard after all. But, it does require some additional work. There is even more work to do, if you want to get an integer (or other numeric value) from the user. If the user types in "123", that will be still be returned as a String object by
the nextLine method of Scanner. You will need to parse [convert] the String object into an int
value or learn to use the nextInt method if you wish to store it in an int
variable or data member. Here's how:
String input = stdin.nextLine(); // from console input example above.
int number = Integer.parseInt( input ); // converts a String into an int value
The Integer class contains conversion methods for changing String data into int values and vice versa. The Integer class is one of several wrapper classes that are defined in the standard Java API. Wrapper classes have class methods for parsing and are also used when you need to store a
primitive value as an object. int
value. The parseInt method of the Integer class performs this action. Be sure to review the Integer
class javadoc for more information about this and other methods of the Integer class.The parseInt method declares that it may throw a NumberFormatException. If the user types any string of characters that can't be parsed into an int
value, a NumberFormatException will be thrown and the program will crash. That can't be a
good thing! But, there is something that you as the programmer can do to keep your program from crashing. You can catch the NumberFormatException. If you don't know what an exception is, read about them in Java Exceptions.
As mentioned above, data can be read from a variety of different sources, including data files stored on devices such as hard disk drives and floppy drives. The file will need to be opened and a Scanner will be attached to the file object. The process is actually very similar to the console input example above. The difference is that the Scanner will be created from a File object instead of the standard InputStream object. This section focuses on inputting characters rather than data bytes.
The discussion and examples in this document explain the procedure when the file to be read is a text file that has valid ASCII characters to represent the data. Here are two new Java I/O classes to review:
java.io.File
- stores information about a file on a computer drive.java.io.IOException
- used to store information about errors that may occur when reading files.Here's a code fragment to illustrate reading a text file. Creating a Scanner connected to a file may cause an IOException which is a checked exception, so be sure to catch the exception or add the throws IOException clause to the method header. See the Java Exceptions web page for more information on handling checked exceptions.
System.out.print( "Enter the filename: " ); // Prompt the user for a file name String fileName = stdin.readLine(); // get a file name from the user java.io.File file = java.io.new File( fileName ); // create a File object if ( file.exists() ) // check that the file exists { // before trying to create a // BufferedReader // Create a Scanner from the file java.util.Scanner inFile = new java.util.Scanner( file ); // For each line in the file, read in the line and display it with the line number int lineNum = 0; // Compare the results of calling the readLine method to null // to determine if you are at the end of the file. while ( inFile.hasNextLine() ) { String line = inFile.nextLine(); // save if needed System.out.println( ++lineNum + ": " + line); } // Close the buffered reader input stream attached to the file inFile.close(); }
import java.util.*
classes.import java.io.*
classes.When you are reading data into your program from a text file, you may need to interpret certain parts of each line differently. This is especially true if you need your program to create objects from text data contained in a file. Individual data items can be placed on different lines of the input data
file, but this creates very long files. It is much more common to place all of the data items for one object on the same line and separate each item with some special character, called a delimiter. In this type of data file, each line of the file represents one record or one object. The example
data file "student_scores.txt
" shown below, contains data for three students and three exams scores for each student.
Each line of input is interpreted as a string of characters for the name, that is followed by three integers for each object created. The delimiter character is the ':'
in the above data file.
The process of splitting a line of text into different parts is known as tokenizing, and each piece is a token. The standard Java library class String includes a method called, split that makes this process convenient for Java programmers. Without this method, you would need to use nested repetition and selection statements to process each character one at a time and determine if it is part of the name or one of the exam scores and then store it accordingly. Java programmers simply need to learn how to use the split method and what the array of String values that is returned will contain. Refer to the String javadoc for more detailed information on methods other than those presented here.
An array of String tokens is created from a String object by using the split method
to create the array. Once you have the array, use the length field to find out how many tokens exist in that array. There is another class that can also be used to split a String into tokens. The StringTokenizer class is in the java.util
package. It allows you to read and process one token at a time instead of getting an array of all tokens.
Here is a code fragment that reads the file shown above and computes the average score for each student listed.
// Make sure that the file student_scores.txt exists and has // valid data records. Otherwise, exceptions will occur. File gradeFile = new File( "student_scores.txt" ); if ( gradeFile.exists() ) { // Create the buffered reader for reading the file Scanner inFile = new Scanner( new File( gradeFile ) ); String line = null; // no line read yet // If line is not end of file continue while ( inFile.hasNextLine() ) { // Read next line of the file line = inFile.nextLine(); // Create a StringTokenizer with a colon sign as a delimiter String[] token = line.split(":" ); String name = token[0]; // Display the content of the first token System.out.print( " Name: " + token[0] ); // Display the total number of tokens remaining this string int numScores = token.length-1; // the name is the first token // Initialize the sum to zero int sum = 0; // Get each score, add it to the sum and print it for ( int i=1; i <= numScores; i++ ) { int score = Integer.parseInt( token[i] ); sum += score; } // Display the average score for this student System.out.println( " average = " + sum/numScores ); } // end while not at end of file // Close the Scanner inFile.close(); } // end if the grade file doesn't exist
Writing data to a file is similar to writing data to the screen. You will open a file for writing and then print to that file any data that you would like to store there. You must remember to close the file or risk having some data not be written and saved to the file. We will use each of these classes.
java.io.PrintWriter
- used to write strings of characters (instead of bytes) to any Writer object.When you intend to write data to a file, you should consider what the appropriate action to take is, if the file already exists. The safest option is to ask the user what to do, and then allow the user to choose: overwrite the file, choose a different filename, or cancel the operation. However, we typically take the easiest way and simply overwrite the file without warning to the user.
The
example shown below assumes that the file opened by the PrintWriter object will be overwritten if it already exists. If you do not want to overwrite the file if it already exists, then you must create and test a File object first. The exists method of the File class will return true
if the file already exists.
// Create a PrintWriter that automatically flushes data // to the output file whenever the println method is used. java.io.PrintWriter pw = new java.io.PrintWriter( "out.txt", true ); // Buffer some data to write to the file (doesn't actually write until flush) pw.print( "Some test data that will be written when flush is called."); // Flush all buffered data to the file. pw.flush(); // Write some data and automatically flush it to the file. pw.println( data ); // Close the PrintWriter for added safety. pw.close();
The nice thing about using a PrintWriter object is that you are already familiar with the print and println methods that are defined for all PrintWriter objects. By choosing the constructor that accepts a String for
the filename and a boolean
value, we are able to set the PrintWriter object so that it will always flush the data buffer on all calls to println. This is safe, but less efficient. It is more efficient to wait until the buffer is full before writing to
disk. In that case, the flush method must be called or the file must be closed to flush the remaining data from the buffer.
Input and output using the standard Java library of classes is quite manageable once you learn to use Java's Scanner and PrintWriter classes connected to files. By using and experimenting with each of the techniques presented here, you will be able to perform some of the most common input and output operations in your Java programs.
EchoSquared.java has examples of console based input and output, written by Deb Deppeler.
ConsoleIO.java has additional examples of console based input and output, written by Jim Skrentny.
FileEcho.java has examples of file based input, written by Deb Deppeler.
FileIO.java has an additional examples of file based input and output, written by Jim Skrentny.
Copyright © 2003,2016 Deb Deppeler. (deppeler@cs.wisc.edu)
Last update on
9/27/2016
Notes:
Here is a program that tries to open a file for reading. The name of the file is given by the first command-line argument .
public class Test { public static void main(String[] args) { Scanner fileIn; File inputFile; try { inputFile = new File(args[0]); fileIn = new Scanner(inputFile); // may throw FileNotFoundException while ( fileIn.hasNext() ) { System.out.println( fileIn.nextLine() ); } } catch (FileNotFoundException ex) { System.out.println("file " + args[0] + " not found"); } catch (Exception ex) { System.out.println("unable to read file contents"); System.out.println(ex.getMessage()); } finally { System.out.println("done"); } } }
Notes:
java.io.FilenotFoundException: foo at java.io.FileInputStream ... at ... at Test.main ...