15.3 Files


15.3 Files

A disk file organizes data on a massive storage device such as a disk device. The main advantage of a disk file is that it provides permanent data storage; a second advantage is that it can support a large amount of data. A third advantage of a disk file is that the data can be interchangeable among several computers, depending on the type of storage device used. On the same computer, disk files can be used by one or more different programs.

A disk file can be set up as the source of a data stream or as the destination of the data stream. In other words, the file can be associated with an input stream or with an output stream. Figure 15.2 illustrates the flow of data and the difference between an input and an output stream.

click to expand
Figure 15.2: Input and output streams.

15.3.1 Text and Binary Files

Text files are human-readable. They contain data that is coded as printable strings. A byte is coded as a single text character. For example, a KJP source program is stored in a text file with a .kpl extension. In the same manner, a Java source program is also stored in a text file. In simple terms, a text file consists of a sequence of characters. Lines are separated by two characters, carriage return (CR) and line feed (LF); these are placed at the end of a line by pressing the Enter key [1].

A binary file is not human-readable. Its data is stored in the same way as represented in memory. Especially for numeric data, the representation in memory is just ones and zeroes. A compiled program is stored in a binary file.

Binary files take less storage space and are more efficient to process. When reading or writing numeric data, there is no conversion from or to string format.

15.3.2 Handling Text Files

The normal procedure for a program that processes data on a file is the following:

  1. Open the file for input or output. This step is called opening the file for input or output; it attaches the file to a stream.

  2. Read data from the file or write data to the file.

  3. Close the file.

For these file processing tasks, Java provides several library classes. Most of the classes for stream I/O are located in package java.io.

15.3.3 Output Text Files

Java provides two predefined Java classes that are used to create objects for opening a text file for output, FileOutputStream and PrintWriter. The following statements declare the two object references and create the corresponding objects to an output text file called mydata.txt.

     object myoutfile of class FileOutputStream     object myoutstream of class PrintWriter     . . .     try begin        create myoutfile of class FileOutputStream               using "mydata.txt"        create myoutstream of class PrintWriter               using myoutfile     endtry 

The previous statements have connected the disk file to an output stream, myoutstream. This opening of the file could generate an exception if the file cannot be created. For this reason, the statements must appear in a try block. To handle the exception, a catch block must immediately follow.

     catch parameters object e of class                        FileNotFoundException      begin        display "Error creating file mydata.txt"        terminate     endcatch 

If the output file cannot be created, an exception is raised (thrown) and statements in the catch block display an error message related to the exception and terminate the program.

The output stream created is used for all output statements in the program with methods print and println of object reference myoutstream.

After the output file has been created, it can be used to write string data. The numeric data must first be converted to string. For example, to convert an integer value to a string value, function valueOf of the class String is invoked. The following statements declare a variable of type integer, int_val, declare a variable of type string, str_val, convert the value of the integer variable to a string, and assign the value to the string variable, str_val.

     variables       integer int_val       string str_val     . . .     set str_val = call String.valueOf(int_val) 

15.3.4 Sample Application

The following class, Fileproc, implements the solution of the salary problem that stores data about employees in a text file. Objects of class Employeec calculate the salary increase and the updated salary.

     import all java.io     description       This program checks for an exception in the       value of age, and writes data to an       output file.  */     class Fileproc is       public       description           This is the main function of the application.           An object of class Employeec calculates the           salary increase and updates the salary.           If the age is zero or negative, an exception           is thrown and caught. This data is written to           an output text file.      */       function main is         variables           integer obj_age           character more_data              real increase              real obj_salary              string obj_name        string str_age        string str_inc        string str_sal              string file_name              string lmessage // message for exception            objects              object emp_obj of class Employeec              object myoutfile of class FileOutputStream              object myoutstream of class PrintWriter              // exception for negative age              object lexecep_obj of class Exception            begin              set myoutstream = null              display "Enter name for output file: "              read file_name              // open ouput file              try begin                 create myoutfile of class FileOutputStream                    using file_name                 create myoutstream of class PrintWriter                    using myoutfile              endtry              catch parameters object e of                    class FileNotFoundException              begin                  display "Error creating file mydata.txt"                  terminate              endcatch              set more_data = 'Y'              while more_data equal 'Y' do                display "Enter person name: "                read obj_name                display "Enter age: "                read obj_age              //    Check for exception              try begin                 if obj_age <= 0                 then                    create lexecep_obj of class Exception                       using                       "Exception: age negative or zero"                    throw lexecep_obj                 endif              endtry              catch parameters object excobj of                    class Exception              begin                set lmessage = call getMessage of excobj                display lmessage                display "Retrying . . . "                display "Enter age: "                read obj_age             endcatch             // continue with processing             display "Enter salary: "             read obj_salary             create emp_obj of class Employeec using                 obj_salary, obj_age, obj_name             set increase = call sal_increase of emp_obj             set obj_salary = get_salary() of emp_obj             display "Employee name: ", obj_name             display "increase: ", increase,                 " new salary: ", obj_salary             // write to output file             call println of myoutstream using obj_name             set str_age = call String.valueOf                 using obj_age             call println of myoutstream                 using str_age             set str_inc =call String.valueOf                 using increase             call println of myoutstream using str_inc             set str_sal = call String.valueOf                 using obj_salary             call println of myoutstream using str_sal             display "More data? (Yy/Nn): "             read more_data             if more_data equal 'y'             then                set more_data = 'Y'             endif           endwhile           call close of myoutstream       endfun main     endclass Fileproc 

On the CD

The KJP code that implements class Fileproc is stored in the file Fileproc.kpl, and the Java code is stored in the file Fileproc.java.

The program, composed of class Fileproc and class Employeec, displays the following input/output when it executes with the data shown:

          ----jGRASP exec: java Fileproc         Enter name for output file:         mydata.txt         Enter person name:         James Bond         Enter age:         54         Enter salary:         51800.75         Employee name: James Bond         increase: 2331.034 new salary: 54131.785         More data? (Yy/Nn):         y         Enter person name:         Jose M. Garrido         Enter age:         48         Enter salary:         46767.50         Employee name: Jose M. Garrido         increase: 2104.5376 new salary: 48872.04         More data? (Yy/Nn):         y         Enter person name:         John B. Hunt         Enter age:         38         Enter salary:         39605.65         Employee name: John B. Hunt         increase: 1980.2825 new salary: 41585.93         More data? (Yy/Nn):         n          ----jGRASP: operation complete. 

The output file, mytest.txt, was created and written by the program and has one data item per line with the following structure:

     James Bond     54     2331.034     54131.785     Jose M. Garrido     48     2104.5376     48872.04     John B. Hunt     38     1980.2825     41585.93 

15.3.5 Input Text Files

Reading data from an input text file implies reading text lines from the input line. If the data items are numeric, then the source string must be converted to a numeric type. Another aspect of input text files is that the program that reads from the file has no information on the number of lines in the text file.

Java provides two predefined Java classes in the io package that are used to create objects for opening a text file for input, BufferedReader and FileReader. The following statements declare the two object references and create the corresponding objects for an input text file called "mydata.txt."

     object myinfile of class BufferedReader     object myreader of class FileReader     . . .     try begin        create myreader of class FileReader               using "mydata.txt"        create myinfile of class BufferedReader               using myreader     endtry 

Opening a text file for input can throw an exception if the file cannot be found. Therefore, the statements that create the two objects must appear in a try block. To handle the exception, a catch block must immediately follow.

     catch parameters object excep of                 class FileNotFoundException     begin         display "Error opening file: ", file_name         terminate     endcatch 

In a similar manner to dealing with the output file creation, if the input file cannot be opened, the statements shown in the catch block display an error message and terminate the program.

After opening the file for input, the program can read input streams from the file, line by line. The Java method readLine, which is defined in class BufferedReader, is invoked to read a line of text data. This data is assigned to a string variable. The statement to read a line of data must be placed in a try block because a reading error might occur. The exception is thrown by method readLine.

One additional complication, compared to writing a text file, is that it is necessary to check whether the file still has data; otherwise, there would be an attempt to read data even if there is no more data in the file.

When there is no more data in the file, the value of the text read is null. The following statements define a try block with a while loop, which repeatedly reads lines of text from the text file.

     try begin         // Read text line from input file         set indata = call readLine of myinfile         while indata not equal null do               // get name               set obj_name = indata               . . .               // read next line               set indata = call readLine of myinfile         endwhile     endtry 

The first statement in the try block reads a text line from the file. All subsequent reading is placed in the while loop.

Because the text file can only store string values, conversion is needed for numeric variables. For example, obj_salary and increase are variables of type double, so the string value read from the text file has to be converted to type double. The following statements read the text line (a string) from the file, and then convert the string value to a value of type double with method Double.parseDouble.

     // get salary     set indata = call readLine of myinfile     set obj_salary = call Double.parseDouble               using indata     // get increase     set indata = call readLine of myinfile     set increase = call Double.parseDouble               using indata 

Method Integer.parseInt would be invoked if conversion were needed for an integer variable.

15.3.6 Sample Application

The following class, Rfileproc, reads the text file that was written by the program presented in Section 15.3.4. This data file has one value stored per line. The values of name, age, salary, and increase are each stored in a different line. The file stores these values for every person. The class computes and displays the total accumulated value of salary and the total accumulated value of increase for several persons.

     import all java.io     description          Reads data from an input file, computes the          total salary, total increase, and          displays the data on the screen.          */     class Rfileproc is       public       description           This is the main function of the application.           If an error occurs when opening the input           file, an exception is thrown and caught.           */       function main is         variables           integer obj_age           double increase           double obj_salary           double total_sal           double total_inc           string obj_name           string str_age           string file_name           string indata           string lmessage // message for exception         objects           object myinfile of class BufferedReader           object myreader of class FileReader           // exception for negative age           object lexecep_obj of class Exception         begin           set myinfile = null           set total_sal = 0.0           set total_inc = 0.0           display "Enter name for input file: "           read file_name           try begin              // open input file              create myreader of class FileReader                 using file_name              create myinfile of class BufferedReader                 using myreader           endtry           catch parameters object e of                 class FileNotFoundException           begin               display "Error opening file: ", file_name               terminate           endcatch           //           try begin               // Read text line from input file               set indata = call readLine of myinfile               while indata not equal null do                   // get name                   set obj_name = indata                   // get age                   set indata = call readLine of myinfile                   set str_age = indata                   // get salary                   set indata = call readLine of myinfile                   set obj_salary = call Double.parseDouble                          using indata                   add obj_salary to total_sal                   // get increase                   set indata = call readLine of myinfile                   set increase = call Double.parseDouble                          using indata                   add increase to total_inc                   //                   // Display and continue with processing                   display "Employee name: ", obj_name,                          " age: ", str_age                   display " increase: ", increase,                          " salary: ", obj_salary                   // read next line from file                   set indata = call readLine of myinfile               endwhile           endtry           catch parameters object myexc of                      class Exception           begin               display "Error reading file: ", file_name               terminate           endcatch           display " --------------------",                       "--------------------------------"           display "Total salary: ", total_sal           display "Total increase: ", total_inc           try begin               call close of myinfile           endtry           catch parameters object exc2 of               class IOException           begin               display "Error closing file: ", file_name               terminate           endcatch       endfun main     endclass Rfileproc 

On the CD

The KJP code with the implementation of class Rfileproc is stored in the file Rfileproc.kpl. The corresponding Java code is stored in the file Rfileproc.java.

When the program executes, it reads data from the text file "mydata.txt." The program gets the values for the individual data items (name, age, salary, and increase) and computes the total salary and increase. The following listing is the one displayed on the screen.

          ----jGRASP exec: java Rfileproc         Enter name for input file:         mydata.txt         Employee name: James Bond age: 54           increase: 54131.785 salary: 2331.034         Employee name: Jose M. Garrido age: 48           increase: 48872.04 salary: 2104.5376         Employee name: John B. Hunt age: 38           increase: 41585.93 salary: 1980.2825          ------------------------------------         Total salary: 6415.8541000000005         Total increase: 144589.755          ----jGRASP: operation complete. 

15.3.7 Files with Several Values on a Text Line

A text file usually contains lines with several values per line, each separated by white spaces or blanks. In this case, the program must read a line of text from the file, separate and retrieve the individual string values, and convert the values to the appropriate types (if needed). The program must repeat this for every line that it reads from the text file. The following text file has three lines, each with various values, some string values and some numeric values.

      James_Bond 54  2331.034 54131.785      Jose_M._Garrido 48 2104.5376 48872.04      John_B._Hunt  38 1980.2825     41585.93 

The Java class StringTokenizer facilitates separating the individual strings from a text line. The following statements declare and create an object of class StringTokenizer, read a line from the text file, and get two string variables, var1 and var2, from the line.

     // declare object ref for tokenizer     object tokenizer of class StringTokenizer     //     // read line from text file     set line = call readLine of input_file     //     // create tokenizer object     create tokenizer of class StringTokenizer using line     //     // get a string variable from line     set var1 = call nextToken of tokenizer     //     // get another string variable from line     set var2 = call nextToken of tokenizer 

To get the number of substrings remaining on a line, the Java method countTokens can be invoked with the tokenizer object. This function returns a value of type integer. A similar function, hasMoreTokens, returns true if there are substrings on the line; otherwise, it returns false.

Class Lfileproc is similar to class Rfileproc, but it reads a line from the text file and separates the individual string variables for name, age, increase, and salary.

On the CD

The KJP code that implements class Lfileproc is stored in the file Lfileproc.kpl. The Java code is stored in the file Lfileproc.java.

[1]In Unix, only LF is placed at the end of the line.




Object-Oriented Programming(c) From Problem Solving to Java
Object-Oriented Programming (From Problem Solving to JAVA) (Charles River Media Programming)
ISBN: 1584502878
EAN: 2147483647
Year: 2005
Pages: 184

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net