Java IO Tutorial

The following is a learning tool designed to explain the basic use of select classes from the java.io package, as well as classes used in conjunction with input and output.

The following classes will be covered:

  1. System
  2. InputStreamReader
  3. BufferedReader
  4. File
  5. BufferedWriter
  6. String Tokenizer
  7. FileReader
  8. FileWriter

Each in turn will be explained with coding examples and written explanations. In order to use the Java classes, we must import the Java input/output package (java.io). Links to JavaTM 2 Platform, Standard Edition, v1.2.2 API Specification outline further methods not covered. import java.io.*;

The System class is used to perform I/O using the system window.

Standard input is envoked: System.in
Standard output is envoked: System.out

Exercise 1

Create a new project, set the location, click on java2 and chose java application. Write the following code and run the application. Hit any key and push return.

import java.io.*;
public class TrivialApplication {
public TrivialApplication ( ) throws IOException{
     int ch;
     ch = System.in.read(); //reads one byte as an integer from the system window
     System.out.println((char)ch); // converts the int to a character value
          //not converting the value would give the character value as an integer
}; // constructor
public static void main ( String args[] ) throws IOException { new TrivialApplication(); };
} // Application

Exercise 2

Remove the char cast, run the application, hold alt button down, push enter the number 255 with the number pad on the right hand side and release the alt key. Push enter. Repeat this with various numbers between 0 -255.

General System.in use includes coupling with read(). int ch = System.in.read() // reads in one byte, returns -1(end). It is important to note that the read process in this case is limited to one byte.

General System.out use includes coupling with println( ) allowing output to the system window. The print methods allow any combination of types to be printed within the same print statement.

Example:

char A = ‘c’;
double B = 2.5;
String C = “Dave”
System.out.println( “Hello ” + C + “, the answer to ” + A + ” equals ” + B);
//This has output to the system window: Hello Dave, the answer to c equals 2.5.

The ln forces a new line (‘/n’) character to be written to the system window, moving cursor to following line.

Exercise 3

Change the first program to output the above example, or something similar. note: There are other methods available in the class.

InputStreamReader is a bridge from byte streams to character streams. It reads bytes and translates them into characters. Each invocation of one of an InputStreamReader’s read( ) methods may cause one or more bytes to be read from the underlying byte-input stream and is declared:

InputStreamReader input = new InputStreamReader(System.in);
In this case InputStreamReader accepts data from System.in and declares input as a reference to the data.

The functionality of InputStreamReader is not much different than System.in.

Exercise 4

Write the following code and run it. You’ll find it is really not much different than a previous exercise in terms of functionality.

import java.io.*;
public class TrivialApplication {
     public TrivialApplication ( ) throws IOException{
          InputStreamReader input = new InputStreamReader(System.in);
          int ch;
          String st;
          System.out.println(“enter a character and push enter”);
          ch = input.read();
          System.out.println(“Character value ” +(char) ch);
     }; // constructor
     public static void main ( String args[] ) throws IOException { new TrivialApplication(); };
} // Application

Exercise 5

Write the following code and run it. This code read a line of characters and stores it in an array. This can be done using System.in as well. Try it!

import java.io.*;
public class TrivialApplication {
     private static final int MAX = 10;
     public TrivialApplication ( ) throws IOException{
          InputStreamReader input = new InputStreamReader(System.in);
          int i;
          int ch[ ];
          ch = new int [MAX];
          System.out.println(“write a line of length ” + MAX + ” push enter”);
          for (i = 0 ; i

Exercise 6

Write the following code and run it. This uses a different read method which reads bytes and stores them in a given array.

import java.io.*;
public class TrivialApplication {
     private static final int MAX = 10;
     public TrivialApplication ( ) throws IOException{
          int i;
          byte ch[ ];
          ch = new byte [MAX];
          System.out.println(“write a line of length ” + MAX + ” push enter”);
          System.in.read(ch );
          for (i = 0 ; i

Creating an instance of BufferedReader allocates memory storage for data input. The primary need for BufferedsReader is that it makes data input, which could be a very inefficient process into a more efficient process. “In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream.” This could lead to many reading steps, and reading is one of the slowest aspects of computer processing. The Buffered reader allows for one reading step by providing data input storage which can then be accessed efficiently. “The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.”

InputStreamReader dave = new InputStreamReader(System.in);
BufferedReader br = new BufferReader(dave);

The buffered reader accepts input from the InputStreamReader by including the dave variable, declares the location to store input from System.in and declares br as the access variable to the memory location storing this input. One can wrap an InputStreamReader within a BufferedReader for efficiency.

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

We will concentrate on reading files into a buffer and then accessing the info in the buffer. Examples of using a buffer with a file will follow.

Creating an instance of File, designates a filename to be the location for character input or output of an object file. The pathname to the current working directory can be specified. The pathname can be either be an absolute (or complete) pathname in that no other information is required to locate the file hat it denotes or a relative pathname which must be interpreted in terms of some other information taken from some other pathname. An abstract pathname has two components. Firstly, an optional system-dependent prefix string, such as a disk-drive specifier, “/ ” for the UNIX root directory, or ” \\ ” for a Win32UNC pathname. The other one is there is a sequence of zero or more string names. This representation varies from operating system to operating system. Here are some examples: UNIX: ” /home/users/2p92/file1 ” DOS: ” C:\home\users\2p92\file1 ” MacOS: ” Macintosh HD:home:users:2p92:file1 ” All three examples reference a file called “file1” on the primary hard drive in the “2p92” directory which exists in the “users” directory which is in the “home” directory. One obvious difference is the path separator character.

File inputFile = new File(“testFile.txt”);
File outputFile = new File(“/home/users/2p92/outFile.txt”);

The above declarations creates a two file objects, one called inputFile which designates testFile.txt, the other called outputFile which designates outFile.txt

Creating an instance of BufferedWriter allocates memory storage for data output. The primary need for BufferedsWritter is that it makes data output, which could be a very inefficient process into a more efficient process. In general, each read request made of a FileWriter causes a corresponding write request to be made of the underlying character or byte stream.” This could lead to many writing steps, and writing is one of the slowest aspects of computer processing. The BufferedWritter allows for one writing step by providing data output storage which can then be outputted efficiently. “The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.” File outputFile = new File(“output.dat”); FileWriter fwr = new FileWriter(outputFile); BufferedWriter out = new BufferedWriter(fwr); The above example designates output.dat, the output File to be referenced by out by including outputFile within FileWritter declaration and in turn including fwr in BufferedWriter declaration. Thus allowing a large amount of character data stored in a memory location to be outputted into a file. Further examples of BufferedWriter will be shown later.

The StringTokenizer class contained in the java.util package will be explained in brief as it is useful in applications using java.io to manipulate strings. StringTokenizer is a Java utility built in method(it does not have to be imported). It’s used to separate a string into tokens (generally individual words) in an application by recognizing delimiters, the white space and comment characters (less the skip comment) and procuring substrings or tokens between delimiters. The procedure to implement StringTokenizer could involve buffering string input using BufferedReader or simply declaring a string within the application. The string is then declared to be a tokenizable object. The application can then apply methods contained in the string tokenizer package to this tokenizable object.

StringTokenizer st = new StringTokenizer( ” this is a test ” );
While (st.hasMoreTokens ()) { Println(st.nextToken( ) ); }

The above code prints the following output: this is a test The stringTokenizer utilizes a variety of methods to enable the tokenization of strings. A select few are listed below:

countTokens( )     Calculates the number of tokens contained in a tokenizable string from the current token.
nextToken (String delim)     Returns the next string Token from a tokenizable string. Counting tokens after calling next token would reduce the token count by one. The current token has been advanced by one.
hasMoreTokens( )     Tests if a tokenizable string has more tokens.
nextElement( )     Returns the next object Token from a tokenizable string

Creating an instance of FileReader allows an application to gain access to character input specified of file type. To implement FileReader an application would first create an object file, ex input file. The inputfile would then be specified as file that can be read.

File inputFile = new File(“test.dat”);
File Reader Joe = new FileReader(inputFile);
Int c;
While ((c = joe.read() !=-1){
System.out.println(“Joe” + c); } joe.close();

In this case the application reads directly from the file. This would be very inefficient if the application had to read many times and thus a buffered reader could be used. The following example combines much of what has been discussed so far.

Input could consist of:

  • joe blow has a dog
  • joe blow has a log
  • joe blow has a pig
  • joe blow has a fig

This example also embeds the FileReader declaration into the buffered reader. The method readLine() reads a string line from the buffered reader, this line would consist of a line of input shown above. Note: a BufferedReader will accept any character input-Stream and a FileReader is just such a stream.

Exercise 7

A) Create a new java application and add the following code.

import java.io.*;
import java.util.*;
/** This application reads input from the File test.dat, stores it in
 ** a memory location for efficient access, tokenizes a line of input data
 ** at a time allowing the application to use methods from the StringTokenizer
 ** class on these lines (or strings).
 **
 ** @author A.Muir
 **
 ** @version 1.0 (date here)      */

public class Application {
       public Application ( ) throws IOException{
              File inputFile = new File(“test.dat”);
              BufferedReader br = new BufferedReader(new FileReader(inputFile));
              int temp;
              StringTokenizer st;
              String c;
              System.out.println(“Joe Blow” + st.countTokens());
              while(true){
                     if((c = br.readLine()) == null){ break; }
                     st = new StringTokenizer(c);
                     temp = st.countTokens();
                     for (int i = 0 ; i

B) Create a data file.

1) Create a new text file.

2) Add the following strings and save it as test.dat .

  • joe blow has a dog
  • joe blow has a log
  • joe blow has a pig
  • joe blow has a fig
  • joe blow likes a tree
  • joe blow likes his tea
  • joe blow has no toes
  • joe blow smiles at me

C) Run the application and figure out how the code works. What would happen if you removed temp and simply wrote st.countTokens() directly in the for loop?

Exercise 8

Use string tokenizers to write out the last two tokens only (eg a dog| a tree…)

Creating an instance of FileWriter allows an application to place character output specified of file type. To implement FileReader an application would first create an object file, ex input file. The inputfile would then be specified as file that can be read.

File inputFile = new File(“test.dat”);
File Reader Joe = new FileReader(inputFile);
File outputFile = new File(“out.dat”);
FileWriter out = new FileWriter(outputFile);
int c;
While ((c = joe.read() !=-1){
       out.write(c);
}
joe.close();
out.close();

In this case the application writes directly to the file. This would be very inefficient if the application had to write many times and thus a BufferedWriter could be used.

public class Application {
       public Application ( ) throws IOException{
           
              BufferedReader br = new BufferedReader(new FileReader(new File(“test.dat”)));
              BufferedWriter out = new BufferedWriter(new FileWriter(new File(“output.dat”)));
              StringTokenizer st;
              String c=””;
              out.write(“Joe Blow”);
              out.newLine();
              while(true){
                     if( (c=br.readLine()) == null) break;
                     st = new StringTokenizer(c);
                     for(int i = 0; i

The above application inputs similar data to FileReader example, although the output for this example differs. Note the spacing left by newline() differs in this example. Play around with nextToken() and countTokens(). What exception is generated if you attempt to get one token too much( ie: add 1 to countTokens( ) )? Why does this code have a flaw? What is it?

Author

Alex Muir

References

Houlahan, R., Muir, A., Hickey, T., Cho, H.,& Mahammed, A. (2000).
Import Java.io. Brock University 2p92 Project
Note: Selected writings reused from this document were written primarily by Alex Muir. Other content may be included in a more advanced tutorial later.
See Specifications below for more detailed java.io information

Java 2 Platform, Standard Edition v1.2 API Specification