Welcome to Lesson 18!


Learning Objectives
By the end of today's class, you should know...
  • How do you write a void method?
  • What is the difference between a void and non-void method?
  • How can one method call another method?
  • How do you write data to a file?
  • How do you read in data from a file?

Announcements

  • Next quiz on Thursday - methods, methods, methods!
    • How to write a javadoc comment
    • How to write a void method
    • How to write a non-void method
    • How to call a void method
    • How to call a non-void method
    • How to trace a program with a method call
  • Lab 9 for Friday
  • Midterm 2 Results:
    • As: 25 (2 100% scores)
    • Bs: 3
    • Cs: 6
    • Ds: 0
    • Fs: 3
    • No Shows: 4
  • Final Project Assigned
  • Women in Computer Science Club meeting tomorrow from 12:30pm-1:30pm in the ATC 203 Computer Lab
    • Attend conferences
    • Learn from industry speakers - Amazon speaker in April!
    • Teach programming in the community
    • Learn skills to help you get a tech job
    • Work on a team project to put on your resume


Review Activity

With a partner, write the following methods:


Name: makes10
  • Takes in 2 integer parameters
  • Returns true if one if them is 10, or their sum is 10

Name: notString

  • Takes in one String parameter
  • Return a new string where "not " has been added to the front.
  • However, if the String already begins with "not", returns the String unchanged.


Void Methods

  • Previously we looked at methods that returned one value
  • Methods returning a value use a return statement
    return result;
  • A method that returns no value is called a void method
  • In Java, void methods are defined like methods that return a value
  • However, the keyword void replaces the return type
  • For example, what do you notice that is different about the following?
    public static void displayDegrees(double degreeFarenheit) {
        double degreeCelsius = 5.0 / 9 * (degreeFarenheit - 32);
        System.out.println(degreeFarenheit
             + " degrees Fahrenheit is equivalent to "
             + degreeCelsius + " degrees Celsius.");
        return;
    }
    
  • There are only two differences between definitions for void methods and other methods:
    • void return type
    • return statement is optional and does not specify a value if used
  • If no return type is specified, the method returns after executing the last statement
  • Here is an example program using the void method shown above

Example Program With a void Method


public static void displayDegrees(double degreeFarenheit) {
    double degreeCelsius = 5.0 / 9 * (degreeFarenheit - 32);
System.out.printf(degreeFarenheit
    + " degrees Fahrenheit is equivalent to "
+ "%.1f degrees Celsius.\n\n", degreeCelsius);
    return;
}

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
double fTemperature;

 System.out.print("Enter a temperature in Fahrenheit: ");
fTemperature = input.nextDouble();

//Notice method call without assigning result to variable
displayDegrees(fTemperature);
}

When to Write void Methods

  • When we use a non-void method, we are asking a question
  • The method returns a value in response to our question
    double square_root = sqrt(9.0);
    
  • When we use a void method, we are giving the computer a command
    displayDegrees(212);
  • We do not expect or receive an answer


Common Errors With void Methods

  • Note that we cannot call a void method from a System.out.print statement
  • For example, the following causes a compile error:
    System.out.println(displayDegrees(fTemperature)); // NO!
  • The reason is that a void methods does not return a value and System.out.println has nothing to print
  • Similarly, we cannot call a void method in an assignment statement:
    double temp = displayDegrees(fTemperature); // NO!
  • There is nothing to assign to the variable temp

Activity 18.1: Printing Squares (10 pts)

  • Remember our programs that used nested for loops to print out shapes.
  • Let's write a similar program with a method that prints squares of different sizes for our user.
  • Open up Eclipse and create a new Java project called Squares.
  • Then, copy and paste the starter code into your file, save it and run it to make sure everything is working properly.

package squares;

/**
 *
 * @author
 */
import java.util.Scanner;
public class Squares {

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

        while (length != -1) {
            System.out.println("I will print squares for you!");
            System.out.print("Please enter the length of one side of the square "
                    + "or -1 to quit: ");
            length = input.nextInt();
            //code to call the method
        }
        System.out.println("Thanks for \"square\" dancing with me!");
    }
   
}

  • Now, write a method that prints squares called printSquares(). Your method should take in an integer argument for the length of one side of the square and should return nothing.
  • Call your method inside the while loop so that it will print out a square given the user input for the length of a side.
  • Run the program again. Does it print out a square?
  • When you are finished, upload your squares.java file to Canvas
  • The output of your program should look identical to the sample output below (except user input will vary).


Activity 18.2: Into the Void (10 pts)

  • Void methods are useful for printing out information in a particular format.
  • Let's consider dates and times.
  • In America, we use the 12 hour clock, but in Europe, the 24 hour clock is used. For example, in America, 8:30 at night is represented as 8:30pm, while in Europe, it is represented as 20:30.
  • In America, we write dates in this format MM-DD-YYYY. In Europe, dates are often written as DD.MM.YYYY
  • Let's write a program that uses void methods to format dates and times.
  • We will print each date and time in both the American and European formats for our user.
  • Open up Eclipse and create a new Java project named DateTime
  • Copy and paste the starter code below into your file:
package datetime;

/**
 *
 * @author
 */
import java.util.Scanner;
public class DateTime {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int year;
        int day;
        int month;
        int hour;
        int minutes;
        String dayEve;
        Scanner input = new Scanner(System.in);

        System.out.println("Welcome! This program will print dates and times "
            + "in both the American and European styles!\n");

        System.out.println("First, let's print a formatted date.\n");
  
        System.out.print("Please enter the current year: ");
        year = input.nextInt();
        System.out.print("Please enter the current month: ");
        month = input.nextInt();
        System.out.print("Please enter the current day: ");
        day = input.nextInt();
        System.out.println();
 
        //call to the formatDateAmerican method here
        //call to the formatDateEuropean method here
  
        System.out.println("\nNow, let's print a formatted time.\n");
  
        System.out.print("Please enter the current hour: ");
        hour = input.nextInt();
        System.out.print("Please enter the current minutes: ");
        minutes = input.nextInt();
        System.out.print("Please enter whether it is \"morning\" or \"evening\": ");
        dayEve = input.next();
        System.out.println();

  
        //call to the formatTimeAmerican method here
        //call to the formatTimeEuropean method here

        System.out.println("\nHave a good day!");
    }
   
}


  • Now, you need to write four methods as follows:
formatDateAmerican
takes as input three integer parameter, one for the year, one for the month and one for the day
prints a formatted version of the date to the console, using the format m/d/yyyy
returns nothing
formatDateEuropean
takes as input three integer parameters, one for the year, one for the month and one for the day
prints a formatted version of the date to the console, using the format d.m.yyyy
returns nothing
formatTimeAmerican
takes as input two integer parameters, one for the hour, one for the minutes, and a string parameter that contains either "morning" or "evening"
prints a formatted version of the time to the console, using the format H:MMam or H:MMpm
returns nothing
formatTimeEuropean
takes as input two integer parameters, one for the hour, one for the minutes, and a string parameter that contains either "morning" or "evening"
prints a formatted version of the time to the console, using the 24 hour clock. Note that there is no am or pm in this format.
returns nothing

  • These methods should be written outside of main.
  • When you are finished writing your methods call them in main in the place indicated by the comments.
  • Upload your dateTime.java file to Canvas.

Your output should look identical the output below when you are finished:





Methods Calling Methods

  • Methods may call other methods
  • Within the body of one method, we can call another method call
  • Methods can call other methods as often as needed
  • We are already doing this when main calls a method
  • The following program calls a "helper" method to help calculate the BMI.
  • Because calculating the BMI is a somewhat complicated process, it is helpful to create a second method to do part of the work for us.
  • The heightToSquareInches method handles turning the height from feet and inches (such as 5'8") into inches squared (such as 68"2).

Example of Methods Calling Methods


/**
     * Calculates a user's Body Mass Index
     *
     * @param feet the user's height in feet
     * @param inches the user's height in inches
     * @param weight the user's weight in pounds
     * @return the Body Mass Index
     */
    public static double calculateBMI(int feet, int inches, double weight) {
        int inches2 = heightToSquareInches(feet, inches);
        double bmi = weight / inches2 * 703;
        return bmi;
    }

    /**
     * Converts height in feet and inches to height in inches squared
     *
     * @param feet the height in feet
     * @param inches the remaining inches
     * @return the height in inches squared
     */
    public static int heightToSquareInches(int feet, int inches) {
        int heightInches = feet * 12 + inches;
        int heightInches2 = heightInches * heightInches;
        return heightInches2;

    }

    public static void main(String[] args) {

        Scanner input = new Scanner(System.in);
        int height_feet, height_inches;
        double weight, bmi;

        System.out.print("Please enter your weight in lbs: ");
        weight = input.nextDouble();

        System.out.print("Please enter your height in feet: ");
        height_feet = input.nextInt();

        System.out.print("Please enter your remaining height in inches: ");
        height_inches = input.nextInt();

        bmi = calculateBMI(height_feet, height_inches, weight);
        System.out.println("Your BMI is " + bmi);
    }


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 ASCII codes 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.

Some Methods that Return Information about a File

Method Description
getName() Returns the name of the file or directory as a String.
getPath() Returns the name of the file or directory as a String.
lastModified() Returns the time that the file was last modified as the number of milliseconds since January 1, 1970.
length() Returns the length of the file as a long type.

Some Methods that work with Directories

Method Description
list() If the object refers to a directory, returns an array of strings naming the files and directories.
listFiles() If the object refers to a directory, returns an array of File objects for the files and directories.
listRoots() A static method that returns an array of File objects representing the drives available to the current system.
mkdir() Creates the directory named by the File pathname.

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

Basic File Streams

  • Since there are two types of files, there are streams to support each type
  • Use character streams to read and write text files:
  • Use binary streams to read and write binary files:

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

Writing to a Text Stream

  • To write text to a file, we use a PrintWriter stream:
    PrintWriter output = new PrintWriter("out.txt"); 
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();
       
    }
   
}



Connecting a Character Output Stream to a File

  • To write to a text file, you create a character output stream
  • To do this, you need to layer two or more classes from the Writer hierarchy
  • An example of how to accomplish this task is shown below

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 stream:
    PrintWriter out = new PrintWriter(data);
    

    If you want to append data 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
20
21
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");
    }
}


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

Classes Connecting a Character Output 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();
    }
}
Wrap Up
  • With your partner, answer the questions from today's learning objectives

Upcoming Assignments