logo

APSU Notes


Streams and File I/O

Savitch 10.1-10.3

Topics

10.1 – Text-File I/O

The Concept of a Stream

  • A stream is a flow of data.
  • Java uses streams for both console and file I/O.
  • An input stream represents data flowing into a program.
  • System.in is an input stream that reads data from the keyboard.
  • An output stream represents data flowing out of a program.
  • System.out is an output stream that sends data to the screen.
  • Console I/O deals with temporary data gathered from and sent to the user.
  • File I/O deals with data on a storage device that can be used again later.

Text Files and Binary Files

  • Data in a file is stored as a sequence of bits.
  • A text file contains a binary encoding of a sequence of characters.
    • Java source files, XML files, and configuration files are all text files.
    • Text files can be read by a text editor.
    • Each character in a text file is encoded as 1 byte (ASCII) or 2 bytes (Unicode).
  • A binary file contains data that is encoded some other way.
    • Java class files, audio files, pictures and video files are all binary files.
    • Data in binary files are stored the same as they are stored in memory.
  • Java uses similar techniques, but different classes to handle text files and binary files.

10.2 – Text-File I/O

Creating a Text File

  • An empty text file can be created in Java using the PrintWriter class.
1
2
3
4
5
6
7
8
9
String fileName = "out.txt"; // the name of the file
PrintWriter outputStream = null; // the stream variable
try { // constructor must be invoked in a try block
  outputStream = new PrintWriter(fileName); // create and open the file
}
catch (FileNotFoundException e) { // problem creating/opening the file
  System.out.println("Error opening the file " + fileName);
  System.exit(0);
}
  • Both PrintWriterand FileNotFoundExceptionmust be imported from the java.iopackage.

Writing to a Text File

  • Once a file has been created and opened it can be written to using println, printor printfjust like System.out.
1
2
outputStream.println("This is line 1.");
outputStream.println("This is line 2.");
  • PrintWriter writes data to a buffer buffer in memory, which can be written to the file when it full or the stream is closed.
  • The stream can be closed using the close method.
1
outputStream.close()
  • Closing a stream causes the system to release any resources used to connect the stream to the file.

Tips for Using PrintWriter

  • A program that creates a file should inform the user that is has finished writing to the file.
  • If a PrintWriterobject is declared in a tryblock, it can only be used in the tryblock.
  • Any object that implements the toStringmethod can be passed to any of the PrintWriterfile writing methods.
  • If any existing file is opened using the PrintWriterconstructor, all of its data will be erased and it will become an empty text file.

Appending to a Text File

  • To append data to an existing file, the file must be opened by creating a FileOutputStreamobject.
  • The resulting object is then passed to the PrintWriterconstructor.
1
outputStream = new PrintWriter(new FileOutputStream(filename, true));
  • The second argument to the FileOutputStreamconstructor indicates data should be written to the end of the existing file.
  • If the file does not exist, Java will create an empty file as normal.
  • Both constructors must be invoked in a tryblock with a catchblock that handles a FileNotFoundException.
  • The FileOutputStreamclass must also be imported from the java.iopackage.

Opening a Text File for Reading

  • To open an existing text file for reading, the file must be opened by a creating a Fileobject.
  • The resulting object is then passed to the Scannerconstructor.
1
2
3
4
5
6
7
8
9
String fileName = "out.txt";
Scanner inputStream = null;
try {
  inputStream = new Scanner(new File(fileName)); // opens the file
}
catch(FileNotFoundException e) { // file is not accessible or does not exist
  System.out.println("Error opening the file " + fileName);
  System.exit(0);
}
  • The Fileclass must also be imported from the java.io package.

Reading from a Text File

  • Once a file is opened for reading it can be read using the Same Scannermethods used to read data from the keyword.
  • The hasNextLine()method can be used to determine if the Scannerhas reached the end of the file.
1
2
3
4
while(inputStream.hasNextLine()) { // loop until end of file is reached
  String line = inputStream.nextLine(); // read the next line
  System.out.println(line); // write the line to the screen
}
  • The file can be closed using the closemethod of the Scannerclass.
1
inputStream.close();

10.3 – Techniques for Any File

The Class File

  • The class Filerepresents file names in a general way.
1
File myFile = new File("treasure.txt");
  • Some stream classes accept a Stringas a file name, but others will only accept a Fileobject.
    • The PrintWriter constructor accepts a File, a String, or a OutputStream.
    • The Scanner constructor accepts a File or an InputStream.
    • The FileOutputStreamconstructor accepts a Fileor a String.

Reading a File Name from the User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
System.out.println("Enter file name");
Scanner keyboard = new Scanner(System.in);
String fileName = keyboard.next(); // read the file name from the keyboard
Scanner inputStream = null;
try {
  inputStream = new Scanner(new File(fileName));
}
catch (FileNotFoundException e) {
  System.out.println("error opening the file " + fileName");
  System.exit(0);
}
String line = inputStream.nextLine(); // read a line from file
System.out.println(line);
inputStream.close();

Using Path Names

  • A path name specifies where to find a file.
  • A full path name is a path to a file from the root directory.
  • A relative path name is a path to a file from the working directory.
  • In UNIX the root directory is /and /is used as separator.
1
/user/smith/homeword1/data.txt
  • In Windows the root directory is C:\and \is used as a separator.
1
C:\homework\hw1\data.txt
  • If a Windows pathname is a string, either \\or /must be used.
1
2
"C:\\homework\\hw1\\data.txt"
"C:/homework/hw1/data.txt"

Method of the Class File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
File fileObject = new File(fileName);
boolean fileOK = false;
while (!fileOK) {
  if(!fileObject.exists()) // checks if there is a file with that name
    System.out.println("No such file");
  else if (!fileObject.canRead()) // checks if the file can be opened for reading
    System.out.println("That file is not readable.");
  else
    fileOK = true;
  if (!fileOK) {
    System.out.println("Enter file name again: ");
    fileObject = new File(keyboard.next());
  }
}

Defining a Method to Open a Stream

  • We can define a method to open a file and return an output stream.
1
2
3
4
public static PrintWriter openOutputTextFile(String fileName)
  throws FileNotFoundException {
  return new PrintWriter(fileName);
}
  • This will not work if this is implemented as a void method:
1
2
3
4
public static void openFile(String fileName, PrintWriter stream)
  throws FileNotFoundException {
  stream = new PrintWriter(fileName);
}
  • The openFilemethod will not change the original PrintWriter object passed as an argument.

Case Study: Processing a CSV File

  • A comma-separated values or CSV file is a text format used to store a list of records.
  • Each record is on a separate line that contains a list of fields separated by commas.
  • Consider a file name Transactions.txtthat contains records of each of the sales entered in a cash register.
1
2
3
4
5
SKU,Quantity,Price,Description
4039,50,0.99,SODA
9100,5,9.50,T-SHIRT
1949,30,110.0,JAVA PROGRAMMING TEXTBOOK
5199,25,1.50,COOKIE
  • The first line of the file identifies the name of each field.
  • We want to write a program to process this file, output the transactions in a readable format, and compute the total sales.

CSV File Processing Algorithm

  • We can use the following algorithm to process the file:
    1. Read and skip the header file of the file.
    2. Repeat while we have not reached the end of the file:
      • a. Read an entire line (one record) from the file as a String.
      • b. Create an array of strings from the line representing the fields of the record.
      • c. Convert any numeric fields from the array to the appropriate numeric data type.
      • d. Process the fields.
  • For step 2b, we can use the split method of the String class to break up the line into its fields:
1
2
String line = "4039,50,0.99,SODA";
String array = line.split(","); // use , as a delimiter
  • For step 2c, we can use the Integer.parseInt and Double.parseDoublemethods to convert the strings to numbers.

CSV File Processing Program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.File;
import java.util.Scanner;

public class TransactionReader {

  public static void main(String[] args) {
    String fileName = "Transactions.txt";
    try {
      Scanner inputStream = new Scanner(new File(fileName));
      String line = inputStream.nextLine(); // skip header line
      double total = 0;

               while (inputStream.hasNextLine()) {
        line = inputStream.nextLine();
        String[] transaction = line.split(",");
        String SKU = transaction[0];
        int quantity = Integer.ParseInt(transaction[1]);
        double price = Double.parseDouble(transaction[2]);
        System.out.printf("Sold %d of %s (SKU: %s) at $%1.2f each. \n",
                          quantity, description, SKU, price);
        total += quantity * price;
      }
      System.out.printf("Total sales: $%1.2f\n", total);
      inputStream.close();
      catch(FileNotFoundException e) {
      System.out.println("Cannot find file " + filename);
    }
    catch(IOException e) {
      System.out.println("Problem with input from file " + fileName);
    }
  }

Powerpoint

Quiz

Quiz 8