Share
Explore BrainMass

Using Scanner and PrintWriter in Java

Convert the program of Project 3 to get its input from a data file and to save its output to a different data file. You can base the program on the sample solution to Project 3 if you want to or on your own Project 3 submission if you prefer.

The following is the specification for the modified AgeAndWeight program.
The program will read the input data for the people to process from a disk file.
The format of the data in the input file will be as specified below.
The program will check if an input file was specified on the command line. If so it will use that file as the input file.
If no input file is specified on the command line the program will ask the user to enter a file name.
The program will check if the input file exists (command line-based or user input-based). If the file does not exist an error message will be displayed and the program will exit.

If the file exists it will be opened for input, the number of people to be processed will be read from the file, the array will be created, and the Person objects will be created and loaded into the array based on the data read from the file.
When reading the input file the program will display a "file too short" error message if the end of the file is reached before the required number of people have been read from it.
Otherwise you can assume that the file is properly structured and there is no need to check for any other type of error in it.

The program will generate identical output to that produced in Project 3 except that the output will be saved to a file named output.txt instead of being displayed on the screen. A sample output.txt file is attached so you can see what it should look like.

The following is a sample run in the the case that no input file was specified on the command line and the test file proj3-input.txt was specified by the user. User input is in bold blue:

Enter the input file name: proj3-input.txt
Processing 4 people from file proj3-input.txt

The following is a sample run in the case that the test input file proj3-input.txt was specified on the command line:

Processing 4 people from file proj3-input.txt

Your program should produce corresponding output reporting the number of people in the file and the file name. If there are not enough people in the file your output error message should look like this as a result of processing the file proj3-input.bad from the command line:

Processing 5 people from file proj3-input-bad.txt
Input file is too short. Aborting.

The following is the format that the data will be stored in the input file:

The first line will contain an integer that specifies how many person records are in the file.
Each following line contains the data for one person. The data fields are placed in the file separated by colons in the following manner:
Last-name:First-name:Middle-initial:Age:Weight

The following is the content of a sample file containing the data given in the sample run for Project 3. This file is attached below as proj3-input.txt:

4
Jones:George:M:25:146.8
Morton:Elizabeth:H:63:225.7
Butler:Alex:B:17:92.3
Rockwell:Amy:C:46:179.3

There are a number of ways in which you can get the individual data fields out of the person data line strings in the file. You are free to do this in any way you want to that works but I am going to offer you a method which is well worth knowing about and that makes this kind of thing pretty easy and gives you an opportunity to use the split() method mentioned in section 8.2.7:

The data fields are separated by a specific single character, the colon ( : ). We can assume that a colon would never be a part of the data in any of these data fields so it works well as a field separator. This is commonly done for data that is intended for machine input rather than for human beings. The String.split() method exists largely because this kind of formatting of data for machine input is so common.

The on-line Java documentation for the String.split() method can be found here: String.split().

If you read an entire line from the file into a String variable (easy to do with nextLine()) you can then process the String using split(). To use split() you just invoke it against the string that you want to split up into data fields giving the character that separates the data fields as the only argument. The method returns an array of strings in which each array element is one of the data fields. The number of data fields that split() found in the string will be length of the array.

For example, if I want to split up a string using the "hat" character, AKA up caret, ( ^ ) as the separator I could do it like this:

String myDataString = "xyz^abc^298^34.5^Hello there!";
String myData[] = myDataString.split( "^" );
for( int i = 0; i < myData.length; ++i )
System.out.println( "Field " + (i+1) + ": " + myData[i] );

would display the following:

Field 1: xyz
Field 2: abc
Field 3: 298
Field 4: 34.5
Field 5: Hello there!

Remembering that the two "numeric" values are really strings containing numeric characters, if we wanted to convert field 3 to an int and field 4 to a double, for example, we could do it like this using the parseXXX() methods introduced in section 2.16.1:

int field3;
double field4;
field3 = Integer.parseInt( myData[2] );
field4 = Double.parseDouble( myData[3] );

Here are a few hints on some of the other things that you need to do:

Checking the command line arguments for an input file:

How do you know if there is a command line argument that provides an input file name?

First you can check the length of the args[] array. If no command line arguments were supplied then args.length will be 0. If one argument was supplied args.length will be 1, etc.

Once you have determined that args.length is at least 1 you can find the first argument in args[0]. You can assume that it is the intended input file name which you can then test for existence.

Checking if the input file exists:

You will need to create a File object for the selected input file. You just need to use the exists() method to find out if the file exists. There is an example in Listing 8.8 that is similar to what you need to do.

Determining if the end of file has been reached:

The hasNext() method as used in Listings 8.8 and 8.9 will work adequately for this. The hasNext() method simply tells you if the stream has something more to read. If not, then you can assume that the end of file has been reached.

The "template" for this program is the Project 3 sample solution. A modified file, AgeAndWeightFromFile.java, is posted along with the pure sample solution. The modified solution includes some comments to help you get the file I/O organized. Attached below you have the following sample input and output files:

proj3-input.txt: Data for the first sample run.
proj3-input-none.txt: Data for the second sample run.
proj3-input-bad.txt: Data that should generate a "file too short" error.
output.txt: Sample output from proj3-input.txt input data.

Attachments

Solution Preview

The main focus of this solution is reading and writing files with Java. Reading a file is done with the Scanner class. The Scanner class constructor can take a File object ...

Solution Summary

This solution shows how to read and write text files in Java.

$2.19