/
08 - Exceptions and Files - Exercise

08 - Exceptions and Files - Exercise

Overview

In this exercise we will read and write to a file in our file system. We will also practice handling exceptions, creating our own exception and unit test our code.

Task 1 - Create a new Employee

  1. Locate and open the project from the last exercise - EmployeeMavenProj.

  2. Create a new class EmployeeFileMain for this task. Give it a main() method.

  3. Define a static method in the same class - call it getInput(). This method will be responsible for interacting with the user. It should take one String parameter - a question to print out. It should read the answer from the terminal - declare and create an InputStreamReader using System.in as its constructor parameter.

    InputStreamReader isr = new InputStreamReader(System.in);
  4. Similarly, declare and create a BufferedReader using your InputStreamReader reference as its constructor argument. Use the readLine() method of BufferedReader to retrieve your keyboard input - that is the String the method should return. The readLine() method is declared to throw an IOException. We have two choices - either we wrap the call to the readLine() method within try block and declare a catch block, or we pass the buck. We will opt for the latter - declare your getInput() method as throwing IOException.

  5. Declare new static method: an inputEmployee() method which will ask for a new employee's details to be entered. From inputEmployee() call getInput() three times - first ask for the first name and store the returned value in a variable nfame. Secondly, ask for the last name - store the return value in lname. Then ask for the age and store the returned value in variable strAge. Convert this value to an int using static method Integer.parseInt() and store in the variable called age.

  6. Create an Employee object passing the three values into its constructor - you may need to create the constructor first!

  7. We need to handle the exception that may be thrown in the getInput() method. We will pass the buck again - declare your inputEmployee() method as throwing IOException. Now it will need to be handled in the main method - there is no other option.

  8. Within your main method, make a call to inputEmployee method - you will see that it won't compile. The call needs to be within try block and we need to provide catch block and capture the IOException. Print out a message that something went wrong.

    try{ inputEmployee() }catch(IOException e){ System.out.println("Problem occurred.") }
  9. Now run the application supplying the name and a numeric age.

  10. Run the application again but supply non-numeric age -i.e. abc. The application with crash since it can't cast abc into an int. You will see a stack trace from NumberFormatException.

  11. Let’s handle that exception. Declare the inputEmployee method as throwing NumberFormatException, in the main method include another catch block to handle it. Make it print

    e.getMessage() + " is an invalid age!"
  12. Run your application again and make sure it can handle non-numeric data.

Task 2 - Read from a File

  1. Create another static method showEmployees(). We will read from a .txt file in this method.

  2. Create a new file in your project - call it Employees.txt. This file should NOT be a java class, just a simple File. Fill it up - type in some sample data

  3. Within your EmployeeFileMain.java create a new variable to hold the path to this file. It should be a constant - the path is not going to change.

  4. Within your showEmployees() method declare and create a FileInputStream with your FILE_PATH as a constructor argument. Declare and create a InputStreamReader using your FileInputStream reference as its constructor argument. Declare and create a BufferedReader using your InputStreamReader reference as its constructor argument.

  5. Create a String variable called data and initialise it with an empty string. While the data is not null read a line from the file and print it out (hint: data = readLine()).

  6. Call close on the BufferedReader when the loop exits.

  7. There are a few points where exceptions may be thrown - we are going to pass the buck again and declare our showEmployees method as throwing IOException. That should cover all possibilities as FileNotFoundException is a subclass of IOException.

  8. In main() method, we include the call to showEmployees() in try block and declare two catch blocks - one for IOException and one for FileNotFoundException. Which one should go first?

  9. You can comment out the call to the inputEmployee part.

  10. Run the application and check that you could see the content of your file printed into the terminal. Try to trigger FileNotFoundException - change your constant variable to a path that does not exist. Is it handled correctly?

Task 3 - Create your own exception

  1. Create a new class called UnderAgeException. It should extend Exception, have a private int age variable, have a public int getAge() method to return the age and a constructor that receives an int and a String, storing the int as the instance variable age and passing the String to the superclass constructor.

  2. Within the inputEmployee() method, after we cast the age to int, check if the age is greater than 18. If it's not, throw UnderAgeException passing the invalid age and a short message into the constructor. It will not compile, someone needs to handle this exception - add UnderAgeException to the declaration of the inputEmployee() method. We will handle it in the main().

  3. In the main() method, add a new catch block to the inputEmployee() try block. Handle the exception - print out that the employee's age is not valid.

  4. You can comment out the showEmployee method call.

  5. Run the application and check that the age is handled correctly.

Task 4 - Write into a file

  1. Back in the inputEmployee method - add code to write the new employee's details into our file.

  2. Declare and create FileOutputStream passing the FILE_PATH variable into tits constructor.

  3. Declare and create OutputStreamWriter passing the output stream into its constructor, last layer is BufferedWriter that will take the OutputStreamWriter.

  4. Call write() method on the BufferWriter object. You'd want to write the employee's details into the file. Are there any suitable methods you can use on the employee object?

  5. Make sure you close the BufferWriter object.

  6. Run you application and check that the txt file has your data. Anything strange?

  7. Hint: maybe use the append() method.

 

Task 5 - Unit test your code

  1. The code we just created is not testable. Most of the methods return void and need user interaction. This is not a great situation for unit testing. We can refactor it though.

  2. Create a new public static methods createEmployee. This will take three String parameters - firstName, lastName, and string version of age.

  3. This method should declare that it can throw NumberFormatException and UnderAgeException.

  4. Copy and paste in the code that casts the string age into an int, the part that checks if the age is greater than 18 and the instantiation of the Employee object. It should return this object.

  5. Change your inputEmployee method to use the above method.

  6. In the test package create a new file EmployeeFileTest. Focus on testing the createEmployee method.

  7. Think about the test data - the firstName and lastName are not important but the age value can cause different exceptions to be triggered.

  8. Identify the test cases.

  9. Create your tests.

 

Related content