Welcome to Lesson 18!


Learning Objectives

By the end of today's class, you should know...

  • How do you use arrays as method parameters
  • What is a File?
  • What is a Stream?
  • What is the difference between "reading" a file and "writing" to a file?
  • How do you use Scanner to read from a file?
  • How do you write to a text file using a PrintWriter object?

1. Lesson 17 Practice Exam Questions

Answer the following questions:

  • Declare an array called pets, and assign it the values "dog", "cat", "rabbit", "bird" in TWO ways (static and not static)
Static:




Non-static:







  • Write a for loop to display the pets array to the console







2. Arrays Continued

Arrays and Methods

  • When writing a method with an array parameter, we place an empty [] after the datatype or parameter name:
    public static void print(int values[]) { //will work for an array of any size
    
  • When we call the method, we do NOT include the []:
    print(data); // name of the array is data
    
  • Instead, we pass in the name of the array.

Example program passing an array to a method

    public class ArrayExample {

    public static void print(int values[]){
        for (int i = 0; i < values.length; i++){

            System.out.println(values[i]);

        }

    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int[] scores = {90, 89, 76, 55, 91};
        print(scores);
     
   }

}

  • Unlike other parameters, you can pass the array into the method and then alter the array inside of the method without needing to return a new array.
  • For example, what do you think will be the result of running the following program?
import java.util.Scanner;
public class ArrayExample {
   
    public static void assignValues(int values[]){
        for (int i = 0; i < values.length; i++){
            values[i] = i;
        }
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int[]  arr = new int[10];
        assignValues(arr);
     
        for (int i = 0; i < arr.length; i++){
            System.out.println(arr[i]);
        }
    }
}
       

  • Notice that when you are passing in the array parameter, you are providing the memory address of the array, rather than the values stored there.
  • Therefore, since the method knows where the array is stored in memory, it can make changes to the array directly inside the method.
  • Note that this paradigm is different from the method below, that takes a primitive parameter.
    • The below method assigns the value 4 to the data variable, not the memory address of the variable num.
    • Therefore, any change that is made to data does not affect num.

    public static void assignValue(int data){
        data = 5; //does not alter num
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int num = 4;
        assignValue(num); //does not alter num
     
       
    }

  • It is also possible to return an array from a method - though this approach is unnecessary, as shown in the above example of a void method that takes an array parameter.
  • An example of a method returning an array is below:


/**
 *
 * @author Jennifer Parrish
 */
import java.util.Scanner;
public class ArrayExample {
   
    public static int[] assignValues(int values[]){
        for (int i = 0; i < values.length; i++){
            values[i] = i;
        }
        return values;
    }


    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int[]  arr = new int[10];
        arr = assignValues(arr);

        System.out.println("After filling the array:");
        for (int i = 0; i < arr.length; i++){
            System.out.println(arr[i]);
        }

       
    }
 
}



Activity 18.1: Exploring Arrays (10 pts)
  • In this exercise we explore declaring, allocating and assigning values to arrays containing lists of data
  • Create a Java project called Arr
  • Add the following method to the code:
    public static void print(int values[]) {
        for (int i = 0; i < values.length; i++) {
            System.out.print(values[i] + " ");
        }
    }
    
  • Compile your code to make sure it has correct syntax.
  • Declare and initialize an array for a list of 10 integer scores:
    int scores[] = {90, 91, 92, 93, 94, 95, 96, 97, 98, 99};
    
  • After declaring and initializing the array, call the print() method using the code:
    System.out.println("Integer exam scores:");
    print(scores);
  • Compile and run the program to make sure you made the changes correctly. When you run the program, the output should look like this:
    Integer exam scores:
    90 91 92 93 94 95 96 97 98 99
    
  • Next, write a method, named addExtraCredit. This method uses a for loop to add 5 points to each exam score in the scores array.
  • The method should have the following signature:      

public static void addExtraCredit(int values[]) {
    //Write the body of the method here
//Note: Do not print anything in this method
//No System.out.print statement(s) go here
    
}

  • Next, call this method, passing in the scores array.
  • Then, call the print method again to display the values, along with the message After adding extra credit:
  • Note: Do NOT print inside of the addExtraCredit method. Call the print method to print the array in main. AddExtraCredit should only add extra credit to the scores. It should not print anything inside the body of the method.
  • Another way to think of it: This method has one purpose only: to add extra credit
  • The print method has one purpose: to print the array
  • Structuring the program to have these two separate methods allows for more flexibility. I am free to add extra credit without having to print the array each time I do so. It is my choice of whether to call printArray to print or not after I have added extra credit.

  • Compile and run the program to make sure you made the changes correctly. When you run the program, the new output should look like this:
    After adding extra credit:
    95 96 97 98 99 100 101 102 103 104
    
  • Declare and initialize an array of double values holding rainfall values (in inches) 23.4, 16.4, 18.9, and 52.7
  • Write another print() method with one parameter for the array of double values.
  • After declaring and initializing the array, call the print() method.
  • Note that you can re-use the name print for this second method. The compiler will know they are different methods because the parameters are different. This is called method overloading.
  • Compile and run the program to make sure you made the changes correctly. When you run the program, the output should look like this:

Integer exam scores:
90 91 92 93 94 95 96 97 98 99
After adding extra credit:
95 96 97 98 99 100 101 102 103 104
Double rainfall in inches
23.4 16.4 18.9 52.7

  • Declare and allocate an array of char values and assign it the vowels a, e, i, o and u.
  • After declaring and initializing the array, write another print method to display it. Again, this method should be named print(). Then, call this method in main.
  • Compile and run the program to make sure you made the changes correctly. When you run the program, the output should look like this:
  • Integer exam scores:
    90 91 92 93 94 95 96 97 98 99
    After adding extra credit:
    95 96 97 98 99 100 101 102 103 104
    Double rainfall in inches
    23.4 16.4 18.9 52.7
    Char vowels
    a e i o u
    

  • When your program gives the above output, upload your program to Canvas.


3. File I/O

About Program I/O

  • Program I/O = Program Input/Output
    • Input to and output from programs
  • Input can be from a keyboard, mouse or file
  • Output can be to a display screen, printer or file
  • Note that files can be both input and output devices for programs
  • Advantages of file I/O:
    • Data still exists after the program ends
    • Input can be automated (rather than entered manually)
    • Output from one program can be input to another
  • To store and retrieve data in a file, we need two items:
    • A file
    • A file stream object
  • We will look at files first

Files

File: a collection of data stored under a common name on a storage medium.

  • Files provide long-term storage of large amounts of data
  • Usually, you store files on non-volatile storage mediums
    • Magnetic disks
    • Optical disks
    • Flash storage, like USB storage devices
  • File are a single sequence of bytes

    Byte 0 Byte 1 Byte 2 ... Byte n−1 End-of-file marker

  • The operating system keeps track of the number of bytes in a file
  • Files must have a name
    • Naming requirements depend on the underlying operating system (OS)
  • The operating system organizes files into directories


Types of Files

  • All data in a file is ultimately just zeros and ones
  • It is up to the program using the file to understand the meaning and internal format of the data
  • In general, programs interpret data using two broad categories: text and binary

Text Files

  • In text files, the bits represent printable characters
  • Files are usually stored as one byte per character (ASCII)
  • Each line is delimited by end-of-line character
  • You can read text files because each byte is interpreted by a program as textual characters
  • Some of these programs, like NotePad, then display the textual data to your computer's screen
  • Since there are many programs that read and display text, text files are called human readable

Binary Files

  • Data other than text is usually referred to as binary data
  • Each bit represents some type of encoded information like program instructions or integer data
  • Binary files are easily read by the computer but not by humans
  • The following table compares binary and text values saved in a file
  • First we consider the value "1234" as Unicodes and compare these bits to a binary value of 1234


Comparing Binary and Textual Data

Description Byte 0 Byte 1 Byte 2 Byte 3
"1234" as char's '1' '2' '3' '4'
"1234" as ASCII codes (bytes) 49 50 51 52
"1234" as ASCII codes (bits) 00110001 00110010 00110011 00110100
(int) 1234 as binary bits 00000000 00000000 00000100 11010010


Creating File Objects

  • File class represents a file on the native file system
  • You create a File object referring to a file
  • Then you can query the object for information about that file

Common Constructors for Class File

Class Description
File(String pathname) Creates a File object that refers to the specified pathname.
File(String parent, String child) Creates a File object that refers to the pathname created by combining the parent and child pathnames.
File(File parent, String child) Creates a File object that refers to the pathname created by combining the pathname of parent with the child pathname.

Examples of Creating Files Objects

  • You can create a File object in the current directory:
    File myFile = new File("myfile.txt");
  • Can create a File object using an absolute pathname
  • Specifies the entire path and file name for the file:
    File myFile = new File("C:/docs/myfile.txt");

Using File Objects

  • We can use File objects for many tasks
  • For instance we can:
    • Test some attributes of files or directories
    • Get information about files
    • Get lists of directory contents
    • Create files and directories
    • Delete files and directories
  • You can see some of the commonly used methods listed below

Some Methods that Test a File

Method Description
canRead() Returns true if the pathname exists and can be read by the program.
canWrite() Returns true if the pathname exists and a program can write to it.
exists() Returns true if the pathname exists.
isDirectory() Returns true if the pathname exists and refers to a directory.
isFile() Returns true if the pathname exists and refers to a file.

Other Methods that work with File Objects

Method Description
createNewFile() Creates a new, empty file if a file with this name does not yet exist.
delete() Deletes the file or directory referred to by the File object.
setReadOnly() Makes the file read-only. If successful, returns true.

Working with Files and Directories

  • The following programs show some uses for the File object

Getting Information About a File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.*;

public class FileInfo {
  public static void main(String[] args) throws IOException {
    File myFile = new File("myfile.txt");
    myFile.createNewFile();
    if (myFile.exists()) {
        System.out.println("Name:     " + myFile.getName());
        System.out.println("Path:     " + myFile.getPath());
        System.out.println("Writable: " + myFile.canWrite());
    } else
        System.out.println("The " + myFile.getName()
                + " file doesn't exist.");
  }
}

Streams

Stream: a one-way transmission path that either delivers data to a destination (screen, file, etc.) or that takes data from a source (keyboard, file, etc.)

  • A stream connects a program to an I/O object
  • Input stream: an object that provides a sequence of bytes to a program

  • Output stream: an object that accepts a sequence of bytes from a program

File Streams

File stream: a one-way transmission path used to connect a program to a file.

  • File streams can be either input or output streams
  • File input streams receive data from a file
  • File output streams send data to a file
  • Each file your program uses will need a separate file stream object

Text Streams

  • Streams are implemented using classes and objects - a topic you will cover in more detail next quarter
  • To write and read text, you use character streams
  • A character stream processes characters through the stream
  • There is a separate set of classes for writing and reading character streams. In this class, we will be using:
    • PrintWriter: Connects a stream to a file for writing data from the program to the file
    • Scanner: Connects a stream to a file for reading data from a file into the program

Connecting a Character Input Stream to a File
  • To "read" from a text file, you need to create a character input stream
  • We can use the same Scanner object we used for reading from the keyboard
  • An example of how to accomplish this task is shown below

Example Connecting a Character Input Stream to a File

import java.io.*;
import java.util.Scanner;
public class Files {
public static void main(String[] args) throws IOException{

File file = new File("scores.txt");
Scanner input = new Scanner(file);
int score = input.nextInt();
System.out.println("Score " + score);
input.close();
}
}

Some Commonly Used Methods of a Scanner Object

Method Description
next() Returns the next token as a String object.
nextLine() Returns the rest of the current line as a String object.
nextDouble() Provides classes to handle text, dates, and numbers
nextInt() Returns the next token as an int value.


Procedure For Reading a Text File
  1. Place import java.io.*; at the top of your program
    1. Note that .* is the wildcard. Using a * will import all classes from that package.
  2. Add throws IOException as part of the signature for main to avoid compiler errors.
  3. Create a File object with a pathname to your file:
    File data = new File("data.txt");
    
  4. Add a Scanner object to parse the data in the file:
    Scanner input = new Scanner(data);
    
  5. Read data using methods calls for the correct type:
    int x = input.nextInt();
    
  6. Close the streams when finished reading:
    in.close();
    

Note that you can nest the constructor calls as shown in the example below

Example Program Reading a Text File

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

import java.io.*;
import java.util.Scanner;

class TextReaderApp {
    public static void main(String[] args)
            throws IOException {
        File data = new File("data.txt");
        Scanner input = new Scanner(data);
        String str = input.nextLine();
        System.out.println(str);

        char ch = input.nextLine().charAt(0);
        System.out.println(ch);

        int x = input.nextInt();
        System.out.println(x);

        double d = input.nextDouble();
        System.out.println(d);

        for (int i = 0; i <= 10; i++) {
            x = input.nextInt();
            System.out.print(x + " ");
        }
        System.out.println();

        input.close();
    }
}

Writing to a Text File:

  • To "write" text to a file, we use a PrintWriter object.
  • We can declare the PrintWriter variable in a similar manner to the Scanner variable:
    PrintWriter out = new PrintWriter("out.txt"); 
  • Note that we can either pass in the name of a file directly, as in the example above.
  • Or, we can pass in a File object, like with the Scanner:
File outfile = new File("out.txt");
PrintWriter out = new PrintWriter(outfile);
  • For consistency with the process for reading from a file using the Scanner, we will practice with the second option above.
  • Once we have created a PrintWriter variable, we can call methods to display the data in a file, just like the ones used by System.out
  • For exampe:
File outfile = new File("out.txt");
PrintWriter out = new PrintWriter(outfile);
out.println("Hello, World!");
out.print("\nGreetings, Universe!");
out.close(); //must close or data will not be written in the file

  • Additionally, like with our Scanner objects, we must close the PrintWriter once we are finished with it
    • Closing the PrintWriter object is necessary, not just good practice, as the data will not be written in the file until the PrintWriter object is closed.


Example program to write out data to a file:

import java.io.*;
public class Files {
    public static void main(String[] args) throws IOException{
    
        File file = new File("scores.txt");
        PrintWriter output = new PrintWriter(file);
       
        output.print("100, 95, 90, 85");
        output.close();  
    }
}

Procedure for Writing a Text File
  1. Place import java.io.*; at the top of your program
    1. Note that .* is the wildcard. Using a * will import all classes from that package.
    2. We need 3 classes here so we will save time by using the * instead of importing all 3 separately (java.io.File, java.io.PrintWriter, and java.io.IOException)
  2. Add throws IOException as part of the signature for main to avoid compiler errors.
  3. Create a File object with a pathname to your file:
    File data = new File("data.txt");
    
  4. Connect the file to a file stream:
    PrintWriter out = new PrintWriter(data);
    

    If you want to append data, rather than writing over the contents of the file, then use:

    PrintWriter out = new PrintWriter(data, true);
    
  5. Write to the file using the print() and println() methods:
    out.println("This is a string");
    out.println('c');
    out.println(1234);
    out.println(1.234);
    for (int i = 0; i <= 10; i++) {
        out.print(i + ",");
    }
    out.println();
    
  6. Close the streams when finished writing:
    out.close();
    

Example Program Writing a Text File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

import java.io.*;

class TextWriterApp {
    public static void main(String[] args)
            throws IOException {
        File data = new File("data.txt");
        PrintWriter out = new PrintWriter(data);
        out.println("This is a string");
        out.println('c');
        out.println(1234);
        out.println(1.234);
        for (int i = 0; i <= 10; i++) {
            out.print(i + " ");
        }
        out.println();
        out.close();
        System.out.println("Finished writing file");
    }
}

Activity 18.2: Two Numbers (10 pts)

  • In this exercise we write a program that copies two numbers from an input stream to the console
  • Create a new Java file and name it TwoNumbers.
  • Then, let's create a text file to test our program.
  • In Eclipse, click on the name of the project. Then, go to File->New->File
  • Name your text file infile.txt.
  • In the file, add a list of numbers each on their own line, like this:
10
20

  • We will read from this file in our program.

  • Now, we will create a second text file.
  • Click on the name of the project again. Then, go to File->New-File
  • Name this file outfile.txt
  • Now, open TwoNumbers.java.
  • Add a main method and place the following import statement above main:
    import java.io.*; 
  • Also, as part of the signature of main(), add throws IOException:
    public static void main(String[] args) throws IOException{
    
  • Declare two int variables at the top of main:
int first;
int second;
  • Add code to create a new File object:
    File inFile = new File("infile.txt");
  • Add statements to read two numbers from the input stream. For example, here is the correct code for reading the first number:
    Scanner input = new Scanner(inFile);
    first = input.nextInt();
    
  • Close the stream when finished reading:
    input.close();
    
  • Next, we will add some code to write to a file.
  • Declare a new File variable for the outfile.txt:
File outFile = new File("outfile.txt");
  • Next, declare a PrintWriter variable and connect it to this File:
PrintWriter out = new PrintWriter(outFile);
  • Using the PrintWriter, we will write some text into our outfile:
out.println("first=" + first);
//add a line of code to print the second number here
  • Lastly, close the PrintWriter:
out.close();
  • Compile and run your modified program to make sure you made the changes correctly.
  • When you run the code, nothing should appear on the console.
  • Instead, open outfile.txt in Eclipse and verify that you have the following contents in your file:
    first=10
    second=20
    
  • When you are finshed, submit TwoNumbers.java to Canvas


4. Wrap Up

  • Assume you have a text file named infile.txt that contains the following data: 13.5 19.0 12.4
  • Write four lines of code to do the following:
    1. Create a new File object to connect to infile.txt
    2. Create a new Scanner object to read from the file
    3. Read the first number from the file and store it as a double variable named num1.
    4. Close the Scanner.












  • Assume you have an empty text file named outfile.txt
  • Write four lines of code to do the following:
  1. Create a new File object to connect to outfile.txt
  2. Create a new PrintWriter object to write to the file
  3. Write the message "Hello World!" to the file
  4. Close the PrintWriter.


~Have a Great Day!~