Project p2 is posted. Will discuss starting later this class.
For long-term storage, we use files (or databases)
Using files of data
Typical format: one line for each object
Last time, we looked at the book example HoursWorked2, pp. 400-401, reading data of form shown on pg. 397
Goal: read this file and report total hours for each employee
File hours2.dat:
101 Erica 7.5 8.5 10.25 8 8.5
783 Erin 10.5 11.5 12 11 10.75
…
format
Id name hours-for-each-day
This data is whitespace-delimited, with line structure
Whitespace: spaces, tabs, newlines (defined, pg. 164)
The plan:
Use one Scanner to read lines, so each line is put in a String “text”
For each line, call processLine(String text),
In processLine, create a Scanner on the String to interpret its data
In this case, the String Scanner can be a just-created Scanner, since the data uses whitespace delimiters—Scanners are born with whitespace-delimer.
Look at code on pg. 401. Program HoursWorked2.
Scanner data = new Scanner(text); // set up a Scanner that stops on whitespace
After the Scanner handling lines has delivered a line, it is held in String “text”, like this:
text = “101 Erica 7.5 8.5 10.25 8 8.5”
Get the 101 with data.nextInt()
Get “Erica” with data.next()
Get 7.5 with data.nextDouble(), …
See this on pg. 401, inside processLine.
Once these data items are in local variables, the results are printed out.
Now consider holding data on cars in a file
Example file: inventory.dat
1G1JF27W8GJ178227, Chevrolet, Cruze, 2011,
1G1KK13WBB2657894, Ford, Taurus, 2010,
…
We may need to handle spaces inside items, such as “Land Cruiser”, or “Grand Marquis”, so we use comma-delimited files, also known as CSV files.
The plan:
Use one Scanner to read lines, like HoursWorked2
For each line, call processLine(String textLine) to interpret the line
Luckily Scanner can parse comma-delimited data
Scanner in = new Scanner(textLine);
In.useDelimiter(“,”);
lineText = “1G1JF27W8GJ178227, Chevrolet, Cruze, 2011,”
Get the VIN with data.next()
Get “Chevrolet” with data.next()
Get “Cruze” with data.next()
Get 2011 with data.nextInt()
Now the HoursWorked2 code has no way to return the full data on a line to its caller because this program is in Chap 6, before objects.
Now with objects, we can collect all the data from the line and put it in an object.
Let’s do that with Automobile.
String textLine = “1G1JF27W8GJ178227,Chevrolet,Cruze,2011,”
public static Automobile processLine(String textLine) {
Scanner data = new Scanner(textLine);
data.useDelimiter(“,”); // scanner delimited by comma
int vin = data.nextInt();
String make= data.next();
String model = data.next(); // again, put data items in local variables
int year = data.nextInt();
// now can load up all the data items into one object, return it to caller
Automoblie car = new Automobile(make, model, year, vin);
return car;
}
Note: we can’t use “extra” spaces with the “,” delimiter, for example:
String line1 = “1G1JF27W8GJ178227, Chevrolet, Cruze, 2011,” // spaces before Chevrolet and 2011
Will set make = “ Chevrolet”, and choke on “ 2011” as an int.
To allow whitespace on both sides of the comma, data.useDelimiter(“\\s*,\\s*”)
Look at ManageCars.java, run it—just prints out Automobiles returned by processLine
See that doesn’t print out well
Fix toString in Automobile
Run ManageCars.java again, see cars printed out
To make a bigger program, we would like to load up a whole array of Automobiles in the program. You can look at ManageCars1.java for this if you want. But now let’s turn to…
Programming Project 2
Here we are tracking the location of various computers in a department. For simplicity, location is given by a simple room number. Each computer is assigned an inventory number—this is a very common practice done by our department. In fact, my workstation has one number and my monitor has another, but we’ll keep this simple.
The basic object is ITSystem, that holds the system’s id number, room no., and #problems so far.
It’s API is
ITSystem(int id, int roomNo, int problems)
void recordProblem() // increment problem count
public int getId()
public int getRoomNo()
public int getProblemCount()
// you add toString()
Example of use:
ITSystem sys = new ITSystem(2, 103, 1);
System.out.println(“system “ + sys.getId() + “ is in room “+ sys.getRoom());
The systems should be read from a file, but for simplicity, we’ll enter them interactively.
Run the provided project.
Look at ITSytem
Look at code using ITSystem in SysInventory
Look at the Javadoc for ITSystem. You can create this pretty version of the API by using the Javadoc button in DrJava. Try it!
In this project, there are two object types, ITSystem and SysInventory. The idea of SysInventory is a place for the whole collection of systems, i.e., the system inventory for the department.
A SysInventory holds an array of ITSystems. The inventory has a name, and a Scanner to talk to a user and take commands. This is an interactive object, unlike the ITSystem, which never interacts directly with a user. It’s API is
SysInventory(String name)
void open(Scanner input) // set up the inventory, with help of input
void doCommands() // process commands: exit, help, print, record-problem
That’s it—no getters here. To find out things, the user has to enter commands. There are more methods, but they are private, no public, so they don’t count in the API.
Continue on this next time.