11. Java I/O

I/O Basics

  • Java programs use streams (a file, memory, a socket) to read input or write output.
  • The java.io package (which you should import for I/O operations) contains a collection of stream classes that support these algorithms for reading and writing. These classes are divided into two class hierarchies based on the data type (either characters or bytes) on which they operate.
  • A byte stream means that the 8-bit representation is mapped without undergoing a character transformation (binary I/O)
  • A character stream means that the binary representation of data will be converted to characters, if output, or characters converted to binary, if input (only examples of character stream I/O will be shown)
  • Streams are grouped by whether they read from and write to data "sinks" (strings, files, or pipes) or process the information (such as buffering or character encoding) as its being read or written.

java.io Classes:

There are many Java I/O library classes, so to simplify this (as the textbook does), let's just look at a few IO classes. Be sure to import java.io.*; to use these:

  • File (java.io.File) - This is the class used in the textbook for simplifying creating files. See Chapter 14 of the textbook for more examples and methods.
  • FileInputStream and FileOutputStream - these streams are used to read from or write to a file on the native- file system
  • PrintWriter, PrintStream - Contain convenient printing methods. These are the easiest streams to write to, so you will often see other writable streams wrapped in one of these.

Terminal I/O

  • Standard output stream (by default is the screen, what we have been mostly using)
    • predefined in the System class by thePrintStream object System.out
    • PrintStream methods for output are printor println (discussed in Java Basics)
  • Standard error stream (by default is the screen)
    • predefined in the System class by the PrintStream object System.err
    • PrintStream methods for output are printor println
  • Standard input stream
    • predefined in the System class by theInputStream object System.in
    • InputStream methods for input are
      • public abstract int read( ) throws IOException
          • Reads the next byte of data from the input stream (byte is stored in an int). The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned (similar to getchar() in C). This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.
        • public int read(byte[] b) throws IOException
          • Reads some number of bytes from the input stream and stores them into the buffer array b. The number of bytes actually read is returned as an integer. This method blocks until input data is available, end of file is detected, or an exception is thrown.
  • Examples of using System.out and System.in have already been given in Chapters 2 and 3 of this java notes.

Text File Output

To write text to a file using default character encoding (not discussed in this course), the following is one way to open a text file:

  • Create a FileOutputStream, constructor declared public FileOutputStream(Stringname) throws FileNotFoundException (creates an output file stream to write to the file with the specified name) :
FileOutputStream outFile=null;
try {
          outFile = 
                   new FileOutputStream("info.txt");
}catch( FileNotFoundException e ){
          System.err.println(e);
          return ; // may want to return an error code
} //end catch
  • Create a PrintWriter which is chained to the FileOutputStream:
PrintWriter prtWriter = new PrintWriter(outFile, true);

To write text to a file using specific character encoding, do the following 3 steps to open the text file:

  • Create a FileOutputStream, as in #1 above
  • Create an OutputStreamWriter specifying the encoding, which is chained to the FileOutputStream:
OutputStreamWriter outStream = 
                   new OutputStreamWriter(outFile, "8859_1");
  • Create a PrintWriter which is chained to the OutputStreamWriter:
PrintWriter prtWriter = 
          new PrintWriter(outStream, true);
  • PrintWriter methods for writing output:
    • public void print(type arg)
      • Print a value of type, which may be boolean, char, char[], double, float, int, long, Object or String. The string produced by String.valueOf(arg) is translated into bytes according to the platform's default character encoding, and these bytes are written in exactly the manner of the write(int) method.
    • public void println(type arg)
        • Same as print except that it terminates the current line by writing the line separator string (defined by the system property line.separator, and may not be newline ('\n'). The argument may be omitted to only terminate the current line.
  • Example:
import java.io.*;
public class TryOutputTextFile{
     public static void main( String [] args ){
      FileOutputStream outFile=null;
      try {
                   outFile = 
                             new FileOutputStream("info.txt");
      }catch( FileNotFoundException e ){
                   System.err.println(e);
                   return ;
      } //end catch
      PrintWriter prtWriter = 
              new PrintWriter(outFile, true);
      prtWriter.println("Writing a String");
      prtWriter.println(Math.PI);
      prtWriter.println(true);
     } // end main
} // end class TryOutputTextFile
  • HERE IS AN EASIER WAY TO OPEN AN OUTPUT TEXT FILE (as shown in the textbook):

(use File and PrintWriter in java.io.*)

File file = new File("myFile.txt");
PrintWriter outfile = new PrintWriter(file);

// now you can call print and println and printf? on outfile

Exercise 11.1

/* Exercise 11.1 Change any of the previous Java programs written that wrote to System.out to write to a text file. */

import java.io.*;
public class Exercise_11_1_WriteTextFile
{

public static void main(String[] args)

{

// Method 1

FileOutputStream oOutFile1 = null;

System.out.println("Write to file");

try

{

oOutFile1 = new FileOutputStream("SampleOutput1.txt");

}

catch(FileNotFoundException e)

{

System.err.println("Error: " + e);

return;

}

PrintWriter oPrintWriter1 = new PrintWriter(oOutFile1, true);


// Write to File

oPrintWriter1.println("A Java method is called what in C/C++? --> Functions");

oPrintWriter1.println("Java is compiled into --> intermediate byte code which is stored in a file with .class extension.");

oPrintWriter1.println("The Java interpreter is called the --> Java Virtual Machine");

System.out.println("End write to file");


// Method 2

// File oOutFile2 = new File("SampleOutput2.txt");

// PrintWriter oPrintStream2 = new PrintWriter(oOutFile2); // Note: still need try catch OR give compile error

// oPrintStream2.println("Hello");

}

}

Text File Input

  • To open a text file for input using the default character encoding the easy way (as shown in the textbook), use the Scanner class:

java.io.File file=

new java.io.File("input.txt");

Scanner scanner = new Scanner(file);

now you may use the scanner methods that you have been with System.in. To check for end of file, you may use thehasNext() Scanner method.

  • To open a text file for input using special character encoding, do the following:
    • Create a FileInputStream, constructor declared public FileInputStream(String name) throws FileNotFoundException(creates a FileInputStream by opening a connection to an actual file, the file named by the path name name in the file system), for example
FileInputStream inFile = null;
try {
     infile = new FileInputStream("info.txt");
}catch( FileNotFoundException e ){
              System.err.println(e);
              return ;
} // end catch
    • Create an InputStreamReader indicating the special character encoding, which is chained to the FileInputStream:

InputStreamReader inStrRdr =

new InputStreamReader(inFile, "8859_1");

    • Create a BufferedReader which is chained to the InputStreamReader:

BufferedReader reader = new BufferedReader(inStrRdr);

Example Program (Opening a file)

Example of opening with special character encoding (using "info.txt" file already created):

import java.io.*;
public class TryInputTextFile{
     public static void main( String [] args ){
      String str="";
      double dnum=0.;
      boolean bool=false;
      FileInputStream inFile = null;
      try {
              inFile = new FileInputStream("info.txt");
      }
      catch( FileNotFoundException e ){
              System.err.println(e);
              return ;
      } // end catch
      InputStreamReader inStrRdr=
              new InputStreamReader(inFile, "8859_1"); 
      BufferedReader reader = new BufferedReader(inStrRdr);
      try {  
              str = reader.readLine();         
              dnum = Double.parseDouble(reader.readLine());
              bool = reader.readLine().equals("true") ;
      }
     catch( IOException ie ){
              System.err.println("Error in input: " + ie);
      }
      catch(NumberFormatException ne){
              System.err.println("Error in input: " + ne);
      } 
      System.out.println(str);
      System.out.println(dnum);
      System.out.println(bool);
     } // end main 
} // end class TryInputTextFile

Exercise 11.2

/*
Exercise 11.2 Change any of the previous Java programs you wrote that read from System.in to read from a text file
    (create the file first).
 */
import java.io.*;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class Exercise_11_2_ReadTextFile
{
    public static void main(String[] args)
    {
        FileOutputStream oOutputFile = null;
        FileInputStream oInputFile = null;
       
        try
        {
            oOutputFile = new FileOutputStream("SystemInput.txt");
            oInputFile = new FileInputStream("SystemInput.txt");
        }
        catch(FileNotFoundException e)
        {
            System.err.println("Error: " + e);
        }
       
        PrintWriter oPrintWriter = new PrintWriter(oOutputFile, true);
        oPrintWriter.println(10);
        oPrintWriter.println(20);
       
        // Method 1: Using default Encoding
        Scanner oScanner = new Scanner(oInputFile);
        int result = 0;
       
        try
        {
            int i = oScanner.nextInt();
            int j = oScanner.nextInt();
            result = i * j;
        }
        catch(InputMismatchException e)        // try to read file with one number as 10.12
        {
            System.err.println("InputMismatchException: " + e);   
        }
        catch(NoSuchElementException e)        // try to read file having only one number
        {
            System.err.println("NoSuchElementException: " + e);
        }
        System.out.println("Result: " + result);
       
        /*
        // Method 2
        InputStreamReader oInputStreamReader = new InputStreamReader(oInputFile);//, "8859_1");        // Encoding argument gives compile error
        BufferedReader oReader = new BufferedReader(oInputStreamReader);
        String s_EachLine = "";
        int result = 0;
        try
        {
            s_EachLine = oReader.readLine();
            int i = Integer.parseInt(s_EachLine);
            s_EachLine = oReader.readLine();                // To Do: Check EOF every time when read from file
            int j = Integer.parseInt(s_EachLine);
            result = i * j;
        }
        catch (IOException e)
        {
            System.err.println("IO Exception: " + e);
        }
        catch(NumberFormatException e)
        {
            System.out.println("Number Format Exception: " + e);
        }
        System.out.println("Result: " + result);
        */
    }
}
/*
// Example program given in class material
import java.io.*;
public class Exercise_11_2_ReadTextFile{
     public static void main( String [] args ){
      String str="";
      double dnum=0.;
      boolean bool=false;
      FileInputStream inFile = null;
      try {
              inFile = new FileInputStream("info.txt");
      }
      catch( FileNotFoundException e ){
              System.err.println(e);
              return ;
      } // end catch
      InputStreamReader inStrRdr=
              new InputStreamReader(inFile, "8859_1");
      BufferedReader reader = new BufferedReader(inStrRdr);
      try { 
              str = reader.readLine();        
              dnum = Double.parseDouble(reader.readLine());
              bool = reader.readLine().equals("true") ;
      }
     catch( IOException ie ){
              System.err.println("Error in input: " + ie);
      }
      catch(NumberFormatException ne){
              System.err.println("Error in input: " + ne);
      }
      System.out.println(str);
      System.out.println(dnum);
      System.out.println(bool);
     } // end main
} // end class TryInputTextFile
*/