CHAPTER 17

FILES

The ability of the computer to store alphanumeric data, graphic images, and so on in files, and its ability to retrieve the contents has revolutionized applications in almost all aspects of life. Therefore, life without files is unimaginable.

Even the programs which we write are stored in files. We write our programs in .java file. It is a text file. We compile our program and create .class file. It is a bytecode file. A file is nothing but a sequential collection of bytes stored with a name.

In Windows OS, file names have optional extension. It helps in identifying the nature of contents of the file. A .class extension tells us that this is a bytecode file. A .wav extension tells us that the file contains sound.

In this chapter, we will explain how to perform reading and writing operations on files on a disk.

17.1 Why Files?

When we work on a computer, data and programs are stored in RAM, which is a volatile memory device. When we switch off the power, the data as well as the program present in it vanishes. When we restart the computer, we may wish to run the same program again. But it is not present in the memory. Therefore, we require a non-volatile memory. It stores our programs (and data too) even when the power is switched off. In computers, floppies, hard disks, and CDs form the secondary memory. The data and programs are stored in it in the form of a file. Thus, the study of files becomes very important.

17.2 File Classification

Let us start our study of file classification with a few questions and answers.

Short Questions and Answers

 

Q. What are the two basic types of files?

A. Files can be classified as either text files or binary files.

Q. How does the internal construction of binary and text files differ?

A. Text files are those which contain normal ASCII text characters (printable). These files are line oriented. An end of line can be represented by new-line character. In DOS, a new line is signified by two characters, LF and FF (ASCII values 10 and 13). The number of characters in a line is not fixed.
Binary files are files of bytes. There is no concept of line. Binary file is a plain sequential collection of (data) bytes.

Q. What are the advantages of text file?

A. They are many:

  1. Text is the most primary method of expressing ourselves. Kids learn “ABC” even before joining a school.
  2. Text file can be created with simple tools like Notepad or sophisticated word processors like Microsoft Word.
  3. It can easily be read or printed.
  4. It can be used to store input as well as output data.

Q. What are the advantages of binary files?

A. There are two main advantages:
Their size is smaller than corresponding text files.
The speed at which programs can read data from them is very high (as compared to text files).

Q. What is the disadvantage of binary files?

A. They cannot be easily read or written by ordinary tools. They need special programs for it.

Q. How can we sub-classify binary files?

A. Binary files can be sub-classified as (1) binary data files and (2) binary program files.

Q. How can we sub-classify data files?

A. Data files can be classified as either input file or output file. An input file can only be read and output files can only be written. This description is only simplistic. But it helps our understanding of files. (It is possible to open a file for both input and output. More of it shall be discussed at a later stage.)

Q. How can we classify data files on the basis of how they are accessed?

A. Data files can be classified as either sequential access files or direct access files. In a sequential access file, components are accessed one after the other (sequentially) whereas in direct access files, any component can be accessed directly (without accessing its previous components). Hence, these files are also called as random access files.

      So far, files have been classified as follows:

  • text files versus binary files
  • input files versus output files
  • data files versus program files
  • sequential access file versus direct access file

We do not want to complicate the issue by trying permutation and combination of these classes though it is understood that a particular file can simultaneously belong to multiple classes (types). A file can be binary sequential data file. A text file can be an input file or an output file. The only thing to note is that text files cannot be random access files.

17.3 Class File

To handle files, Java offers us a very useful class named File. This class has many constructors and methods. Let us study it in an informal way.

We can construct an object of this class by simply calling a constructor as shown as follows.

 File f1 = new File( “abc.txt”);

The computer creates an object of class File with name abc.txt. Here we have not specified any directory. Hence, our default working directory is assumed. The computer associates this symbolic name f1 with an actual file name (as understood by the OS) abc.txt. The file with this name may or may not exist in the current directory. Please note that this constructor has created an object of type file and not an actual file.

To test whether such a file exists or not, Java provides Boolean method exists(). Let us study this with the help of a program.

Problem: Write a program to test whether a given file exists in the current directory.

Solution: See Program 17.1.

 

PROGRAM 17.1 Test for File Existence

 //             file1.java

 import java.io.* ;

 class file1

  {  public static void main(String[] args) throws Exception

       {  File f1 = new File(“abc.txt”);

          System.out.println(“<---file1.java starts--->”);

          if( f1.exists() ) System.out.println(“File exists”);

              else System.out.println(“ File does not exists”);

       };

  }

 

If you run this program, you will get the following output.

 

Output

 <---file1.java starts--->

 File does not exists

 

We know that files can be used for either input or output. When we create data files and want to use them for reading, we do not want the program to accidentally delete or modify it. The simplest way is to make it read-only. (This is possible in every OS.) Once a file is made “read-only”, a program cannot write to it.

Java allows us to test whether files are read-only or not. It supports two methods canRead() and canWrite() for this purpose.

Problem: Write a program to test whether a file exists in the current directory. Also, test if you can read from or write to that file.

Solution: If a file is read-only, we cannot write to it. However, Java has provided two separate methods. So we will use both of them (see Program 17.2).

 

PROGRAM 17.2 Test for Read–Write

 //             file2.java

 import java.io.* ;

 class file2

   { public static void main(String[] args) throws Exception

       {  File f1 = new File(“abc.txt”);

          System.out.println(“<---file2.java starts--->”);

          if( f1.exists() ) System.out.println(“File exists”);

                else System.out.println(“ File does not exists”);

          if( f1.canRead() ) System.out.println(“can read “);

                else System.out.println(“ cannot read”);

          if( f1.canWrite() ) System.out.println(“can write “);

                else System.out.println(“cannot write”);

       };

   }

 

If you run this program, you will get the following output.

 

Output

 <---file2.java starts--->

 File exists

 can read

 cannot write

 

Before running Program 17.2, a file with this name was created in the current directory. We deliberately made it read-only (by setting property in Windows OS). Hence, we get this particular output.

While working with methods in this class, many times we have to deal with the name of the path where the file is placed. We can use absolute pathname or abstract pathname. Absolute pathname specifies the path starting from the drive letter. Abstract pathname indicates the relative path, that is relative to current working directory.

Table 17.1 illustrates all the important methods supported by class File.

 

Table 17.1 Summary of Methods: Class File

boolean canRead() Tests whether the application can read the file denoted by this abstract pathname.
boolean canWrite() Tests whether the application can modify the file denoted by this abstract pathname.
int compareTo(File pathname) Compares two abstract pathnames lexicographically
int compareTo(Object o) Compares this abstract pathname to another object.
boolean createNewFile() Atomically creates a new, empty file named by this abstract pathname, if and only if a file with this name does not exist.
static File createTempFile(String prefix, String suffix) Creates an empty file in the default temporary-file directory, using the given prefix and suffix to generate its name.
static File createTempFile(String prefix, String suffix, File directory) Creates a new empty file in the specified directory, using the given prefix and suffix strings to generate its name.
boolean delete() Deletes the file or directory denoted by this abstract pathname.
void deleteOnExit() Requests that the file or directory denoted by this abstract pathname be deleted when the virtual machine terminates.
boolean equals(Object obj) Tests this abstract pathname for equality with the given object.
boolean exists() Tests whether the file denoted by this abstract pathname exists.
File getAbsoluteFile() Returns the absolute form of this abstract pathname.
String getAbsolutePath() Returns the absolute pathname string of this abstract pathname.
File getCanonicalFile() Returns the canonical form of this abstract pathname
String getCanonicalPath() Returns the canonical pathname string of this abstract pathname.
String getName() Returns the name of the file or directory denoted by this abstract pathname.
String getParent() Returns the pathname string of the parent of this abstract pathname, or null if this pathname does not name a parent directory.
File getParentFile() Returns the abstract pathname of the parent of this abstract pathname, or null if this pathname does not name a parent directory.
String getPath() Converts this abstract pathname into a pathname string.
int hashCode() Computes a hash code for this abstract pathname.
boolean isAbsolute() Tests whether this abstract pathname is absolute.
boolean isDirectory() Tests whether the file denoted by this abstract pathname is a directory.
boolean isFile() Tests whether the file denoted by this abstract pathname is a normal file.
boolean isHidden() Tests whether the file named by this abstract pathname is a hidden file.
long lastModified() Returns the time that the file denoted by this abstract pathname was last modified.
long length() Returns the length of the file denoted by this abstract pathname.
String[] list() Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname.
String[] list(FilenameFilter filter) Returns an array of strings naming the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter.
File[] listFiles() Returns an array of abstract pathnames denoting the files in the directory denoted by this abstract pathname.
File[] listFiles(FileFilter filter) Returns an array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter.
File[] listFiles(FilenameFilter filter) Returns an array of abstract pathnames denoting the files and directories in the directory denoted by this abstract pathname that satisfy the specified filter.
static File[] listRoots() List the available file system roots.
boolean mkdir() Creates the directory named by this abstract pathname.
boolean mkdirs() Creates the directory named by this abstract pathname, including any necessary but non-existent parent directories.
boolean renameTo(File dest) Renames the file denoted by this abstract pathname.
boolean setLastModified(long time) Sets the last-modified time of the file or directory named by this abstract pathname.
boolean setReadOnly() Marks the file or directory named by this abstract pathname so that only read operations are allowed.
String toString() Returns the pathname string of this abstract pathname.
URL toURL() Converts this abstract pathname into a file: URL.

 

Many other facilities can be seen in Section 17.11 (Program 17.13). Now, after studying class File, we want to use files for reading and writing. To begin with, let us start our study with text files.

17.4 Text Files

Let us first study how to create a text file and write to it. For this purpose, we need class FileWriter. Let us try a simple program.

Problem: Write a program to create a text file. Write in this file Name of a person and his weight in kilograms.

Solution: See Program 17.3.

 

PROGRAM 17.3 Introduction to Text File

 //             fo3.java

 import java.io.* ;

 class fo3

   {  public static void main(String[] args) throws Exception

          {  String s1 = “Anthony Gonsalves”;

             String s2 = new String(“56.3”) ;

             System.out.println(“<---fo3.java--->”);

             FileWriter f2 = new FileWriter(“fo3.dat”);

             f2.write(“my name = “ + s1 + “ ”);

             f2.write(“My Weight = “ + s2);

             f2.close();

             System.out.println(“file fo3.dat created”);

          }

 } ;

 

If you run this program, you will get the following output.

 

Output

 <---fo3.java--->

 file fo3.dat created

 

If you try to inspect the created text file, it will appear as follows:

 

Text File fo3b.dat

 my name = Anthony Gonsalves

 My Weight = 56.3

 

Please note that method close() belongs to class FileWriter. It closes this writer and flushes any pending data. In effect, it closes the file too.

Now it is the time to read a file. Text files can be read one character at a time, but it is advantageous to read the entire line at a time. Java supports a very useful class String. It is suitable for reading one line of text at a stretch. We can get (extract) all the characters from a string easily.

Problem: Write a program to open and read a text file line by line.

Solution: See Program 17.4.

 

PROGRAM 17.4 Reading a Text File

 //         fi2.java

 import java.io.* ;

 class fi2

 {  public static void main(String[] args) throws Exception

      {  String s1 ;

       //    String s2 ;

         boolean flag ;

         System.out.println(“<---fi2.java--->”);

         FileReader f1 = new FileReader(“fi2.dat”);

         BufferedReader fin = new BufferedReader(f1);

         while ( fin.ready() )

             {  s1 = fin.readLine();

                System.out.println(s1);

             }

        fin.close();

      }

 }

 

If you run this program, you will get the following output.

 

Output

 <---fi2.java--->

 Hello!

 This is a text file.

 You are reading line by line.

 Thank You for reading me.

 

Note the function fin.ready().

17.5 Formatted File Input

Text files can be used to store the data in a formatted manner. Consider a case of a text file which stores the colours. A colour has a name and values of RGB colour components. A typical file is shown as follows:

 

Input Text File— col_values.text

Input Text File

It is possible to read such a file and extract data from it.

For reading files, we use class FileReader. It is capable of reading files. However, for efficiency purpose, it is necessary to use a class BufferedReader along with the FileReader class. Consider the following program.

Problem: Write a program to read an input file named col_values.txt and get colour names and RGB values.

Solution: When we inspect the input file, we note that

  • 15 columns are reserved for colour name (string).
  • There are three colour values in 10 columns each.
  • Colour values are in hexadecimal notation.

Now we read one line at a time in a string. Get name and values of colours in sub-strings. As sub-strings may have leading and trailing blanks, we trim them. Lastly, hexadecimal colour values are converted into integer by method parseInt() (see Program 17.5).

 

PROGRAM 17.5 Reading a Formatted File

 //   format3.java

 //   Simple table

 //   formatted input.

 import java.io.* ;

 class format3

 { public static void main(String[] args) throws IOException

       {  int i,j,k ;

          char box[] = new char[51];

          FileReader f1 = new FileReader("col_values.txt");

          BufferedReader Jin = new BufferedReader(f1) ;

          System.out.println("<---format3.java--->");

          for(i=1; i<=4; i++) // knowing 4 lines in file

             {   String sb0, sb1,sb2,sb3,sb4,stemp ;

                 int red, green, blue=0 ;

                 sb0 = Jin.readLine();

                 k= sb0.length();

                 stemp = sb0.substring(0,15);

                 sb1= stemp.trim();

                 stemp = sb0.substring(15,25);

                 sb2 = stemp.trim();

                 red = Integer.parseInt(sb2,16);

                 stemp = sb0.substring(25,35);

                 sb3 = stemp.trim();

                 green = Integer.parseInt(sb3,16);

                 stemp = sb0.substring(35,37);

                 sb4 = stemp.trim();

                 blue = Integer.parseInt(sb4,16);

                 System.out.println(sb1+ " " + red + " " +green +" "+blue);

             }

       }

 } ;

 

If you run this program, you will see the following output.

 

Output

output

You may wonder what the use of this program is. Well, it shows you how to read and accept colour data. With little modification, you can build an array of colour information and use it in graphics programs.

17.6 Reading File with Format-Free Data

Old programming languages like Fortran and COBOL accepted only formatted data. In a formatted data, elements appear in fixed columns. Many times data may not be properly formatted. Programming languages like Pascal boasted of reading format-free data. This facility continued in languages like C and C+ +.

When data elements are separated by any number of separating characters like blanks and tabs, such data is called format-free data. To read such data, Java provides a class StringTokenizer. It extracts tokens from a string. It implies that it automatically skips all separating characters. Once we have a string which contains a known type of data like integer or double, extracting data from it becomes very simple.

Problem: A data file contains the data of a SUDOKU puzzle. Every line contains a row number, a column number, and the value. These numbers (integers) are separated by any number of blanks and/or tabs. In other words, they are present in format-free manner. Write a program to read this data in an array.

Solution: We will read data line by line in a string. Subject this string to StringTokenizer.

As data may have maximum 81 rows, array will have 81 rows and three columns ( see Program 17.6).

 

PROGRAM 17.6 Using StringTokenizer

 //       token1.java

 import java.io.* ;

 import java.util.* ;

 class token1

 { public static void main(String[] args) throws IOException

       {  int a[][] = new int[81][3] ;

          String line = null;

          String str1,str2,str3 ;

          int i,j,N;

          i=0;

          try {

                 FileReader f1 = new FileReader("token1.txt");

                 BufferedReader br = new BufferedReader( f1);

                 while ((line = br.readLine()) != null)

                  {     System.out.println("line read is: " + line);

                        j=0;

                        StringTokenizer st = new StringTokenizer(line);

                        while (st.hasMoreTokens())

                           {  str1 = st.nextToken() ;

                              a[i][j] = Integer.parseInt(str1);

                              j++;

                           }

                 i++;

             }

             br.close();

         }

      catch(Exception e)

         {   System.out.println("Some Error"); }

      N=i-1;

      System.out.println("Now printing array a");

      for(i=0;i<=N;i++)

          {  for(j=0;j<3;j++)

                System.out.print(a[i][j]+" ");

                System.out.println();

          }

      }

 }

 

If you run the program, you will get the following output.

 

Output

 line read is: 1        2  3

 line read is: 3  4     5

 line read is: 5  6    7

 Now printing array a

 1      2        3

 3      4        5

 5      6        7

17.7 Binary Files

As mentioned earlier, there are certain advantages of binary files. Let us try to create and use binary files. These files are used to store data. Hence, the simplest example will be of storing a few integers. Study the following program.

As we are writing binary data in a file, we have to use class FileOutputStream embedded in class DataOutputStream.

Problem: Write a program to create a binary data file binfile1.dat. The file should contain first 10 odd integers.

Solution: See Program 17.7.

 

PROGRAM 17.7 Creating Binary File

 //       binfile1.java

 import java.io.* ;

 class binfile1

   {  public static void main(String[] args) throws Exception

         {  int i;

            System.out.println("<---binfile1--->");

            FileOutputStream fx = new

                 FileOutputStream("binfile1.dat");

            DataOutputStream f2 = new DataOutputStream(fx);

            for(i = 1;i<20;i=i+2)

              { f2.writeInt(i);

              }

            f2.close();

            System.out.println("file created successfully");

         }

 } ;

 

This program creates the file binfile1.dat. As stated earlier, you cannot see this file in word processor and will need a program to see the contents of that file. One may ask what is the use of such binary files. Practically, every large data file is stored as binary file. Large databases are also binary files. But DBMS software comes with built-in programs to view them. Let us write a simple program to read a binary file.

When we want to read a binary file, we have to use class FileInputStream embedded in class DataInputStream.

Problem: Write a program to read a binary data file binfile1.dat and display its contents. It is known that the file contains 10 integers.

Solution: See Program 17.8.

 

PROGRAM 17.8 Reading a Binary File

 //       binfile2.java

 import java.io.* ;

 class binfile2

 { public static void main(String[] args) throws Exception

       {  int i,k;

          System.out.println(“<---binfile2--->”);

          FileInputStream fy = new

                 FileInputStream(“binfile1.dat”);

          DataInputStream f1 = new DataInputStream(fy);

             for(i = 0;i<10;i++)

                 {  k=f1.readInt();

                    System.out.println(k + “ “);

                 }

             f1.close();

          }

 };

 

If you run this program, you will get the following output.

 

Output

 <---binfile2--->

 1

 3

 5

 7

 9

 11

 13

 15

 17

 19

 

This console output displays the contents of binary file binfile1.dat generated by Program 17.7.

17.8 Files for Objects

In the previous section, we first created and then read a binary file consisting of integers. We can do that for any other primary data type like float, long, and double. A file can contain different data types as well. In early days of computer programming, binary files were used to contain records (see Box 17.1). In terms of object-oriented language, an object represents a record. Hence, a binary file can be used to store objects. (Of course, all belong to the same class.) (See Box 17.2.)

BOX 17.1 Record

Record is a very popular term of old programming languages. A record means collection of variables in a bundle. In C/C+ +, it is called struct. Actually, an object is improvised version of struct. Type class can also represent struct. In C+ +, both class and struct are available. Java developers decided to drop the type struct.

BOX 17.2 Why all Elements of Binary File should be Identical

Theoretically, it is possible that a binary file can contain variables of different primitive types. But when you read such a file, you must know the exact sequence of the data in that file. This is practically a very difficult task. We will need another file to keep this information, and the speed with which we read will also decrease. Also, we will not be able to jump to the nth record directly. This prevents any arbitrary combination of primitive data types in a file. Hence, a binary file will have all integers or all bytes or all doubles. Though we said primitive data types, the point is valid for objects too.

Let us write a program which creates a file for objects and reads it back.

Problem: Write a program to create a (binary data) file of objects. The file should contain five objects of class complex number. Next, open that file for reading and fill the array of complex numbers from the file.

Solution: To write binary data, we have to use class FileOutputStream embedded in class DataOutputStream. When we want to read that file, we have to use class FileInputStream embedded in class DataInputStream (see Program 17.9).

 

PROGRAM 17.9 File for Objects

 //       objfile2.java

 import java.io.* ;

 class Complex

      { double x, y ;

        void show()

           {  System.out.print(“ Complex number: “ );

              System.out.println(x +” +j “+ y);

           };

       Complex(double x1, double y1)

           {  x=x1;

              y=y1;

           };

       } ;

 class objfile2

 { public static void main(String arg[]) throws Exception

       {  int i;

          Complex n1, n2, n3, n4, n5 ;

          System.out.println(“--->objfile2.java starts<---”);

          double x, y ;

 FileOutputStream fx = new

          FileOutputStream(“objfile2.dat”);

          DataOutputStream f1 = new DataOutputStream(fx);

          n1 = new Complex(3.1, 5.1);

          n2 = new Complex(5.1, 7.2);

          n3 = new Complex(7.1, 9.3);

          n4 = new Complex(9.1, 11.4);

          n5 = new Complex(11.1,13.5);

          System.out.println(“Writing data to file”);

          f1.writeDouble(n1.x);

          f1.writeDouble(n1.y);

          f1.writeDouble(n2.x);

          f1.writeDouble(n2.y);

          f1.writeDouble(n3.x);

          f1.writeDouble(n3.y);

          f1.writeDouble(n4.x);

          f1.writeDouble(n4.y);

          f1.writeDouble(n5.x);

          f1.writeDouble(n5.y);

          f1.close();

 //       Now the same file will be open for input

          FileInputStream fy = new

          FileInputStream(“objfile2.dat”);

          DataInputStream f2 = new DataInputStream(fy);

          Complex A[] = new Complex[5];

 //       reading from file into an array

          System.out.println(“Reading data from file”);

          for (i=0 ; i< 5; i++)

             {   x = f2.readDouble();

                 y = f2.readDouble();

                 A[i] = new Complex(x, y);

             }

          System.out.println(“Displaying data from array”);

          for (i=0 ; i< 5; i++)

             A[i].show();

       }

 }

 

If you run this program, you will get the following output.

 

Output

 --->objfile2.java starts<---

 Writing data to file

 Reading data from file

 Displaying data from array

 Complex number: 3.1 +j 5.1

 Complex number: 5.1 +j 7.2

 Complex number: 7.1 +j 9.3

 Complex number: 9.1 +j 11.4

 Complex number: 11.1 +j 13.5

 

Important: So for we have not discussed any limitations on objects that can be stored in a binary file. The object must contain only basic data types. It should not contain strings. Strings have no fixed length. Hence, different objects will have different lengths. It will be difficult to handle them. In other words, the object we want to handle must get converted into a fixed number of bytes. This was not the case with text files. Text files can have every line of different length.

17.9 Random Access File

As mentioned earlier, a file can be opened for either reading or writing. This is a simplistic model of files. Nevertheless, it helps us in understanding and using the files easily. In early days of computing, files were strictly sequential. Data was to be read and processed from these files, and the output was kept in another file. For example, the basic pay of an employee was to be read as the data file, and salary statements (or salary slips) were written to output file.

Nowadays the scenario has changed. Databases have become common. Transaction processing has become “online”. It calls for a file to be read and written simultaneously. In such a case, there is no meaning to sequential accessing of a file. Access has to be “random”, and such files are called random access files. Random means we should be able to reach to a particular position directly. Therefore, such files are also known as direct access files. Such access puts a restriction on the file. All the elements of the file should be of same type. The type can be either elementary type or an object in general.

Figure 17.1 shows a schematic random access file. To allow us to work with such files, Java provides a class RandomAccessFile.

Figure 17.1 Random Access File

Figure 17.1 Random Access File

This class implements interfaces DataInput and DataOutput. These interfaces define basic input/ output methods.

There are two constructors for this class.

RandomAccessFile(File fileObject , String access) throws
FileNotFoundException

and

RandomAccessFile( String filename, String access) throws
FileNotFoundException

Access string can be either “r” or “rw” signifying read or read–write operation.

Let us study this class with a program.

Problem: Write a seat reservation program using random access file. Consider a hill station with a tourist helicopter. Assume that it has 10 seats numbered 1 to 10. Assume the following situation:

  • A tourist comes to a booking counter.
  • He demands a particular seat (number).
  • Computer checks if seat is available.
  • If so, it issues a ticket with the requested seat number.
  • If the seat is already booked, tourist must request another seat.

Solution: To begin with, all seats are free. Hence, all are marked with value 0. Please note that the ticket numbers start from 1. Hence, writing ticket number 0 is same as no ticket is issued for this seat.

When a seat number is requested, using seek instruction, we try to find the data (ticket number). If the ticket number is zero, we write the current ticket number to this seat.

At the end of the day, we want to have a summary. It may be noted that random access file can be accessed sequentially as well.

Hence, we go to the first record and keep on reading the seat numbers.

See Program 17.10.

 

PROGRAM 17.10 Random Access File

 //             rand1.java

 import java.io.* ;

 class rand1

   {   public static void main(String[] args) throws Exception

           {  int i,k,num,Tnum;

              int request = 0 ;

              int data[] = { 3, 5, 6, 5, 3, 4 , 9, 7, 2, 1 } ;

              int ticket_number = 1 ;

              System.out.println("program rand1.java starts");

              RandomAccessFile frand = new

                        RandomAccessFile("rand1.dat","rw");

              for(i = 0;i<11;i++)

                  {  frand.writeInt(0);

                  }

               // data initialisation over

               // live transation starts 6 in number

               while (request < 6)

                   {  k = data[request++];

                      System.out.println("Requested seat number : "+ k);

                      frand.seek(4 * k );

                      num = frand.readInt();

                      if( num == 0 ) // seat availble

                         {   frand.seek(4 * k ); //very important

                             frand.writeInt(ticket_number); // to file

                             System.out.print("Seat reserved ");

                             System.out.print(" ticket number " + ticket_number);

                             System.out.println(" seat number " + k );

                             ticket_number++;

                        }

                        else

                             System.out.println(" sorry this seat is booked");

                  }

           // printing summary

           System.out.println(" printing summary " );

           System.out.println("seat ticket");

           frand.seek(4 * 0 );

           for(i=0;i<10;i++)

                  {  Tnum = frand.readInt();

                     System.out.println(i + " " + Tnum);

                  }

           frand.close();

   }

 }

 

If you run this program, you will get the following output.

 

Output

 Requested seat number : 3

 Seat reserved ticket number 1 seat number 3

 Requested seat number : 5

 Seat reserved ticket number 2 seat number 5

 Requested seat number : 6

 Seat reserved ticket number 3 seat number 6

 Requested seat number : 5

   sorry this seat is booked

 Requested seat number : 3

   sorry this seat is booked

 Requested seat number : 4

 Seat reserved ticket number 4 seat number 4

   printing summary

 seat ticket

 0      0

 1      0

 2      0

 3      1

 4      4

 5      2

 6      3

 7      0

 8      0

 9      0

17.10 Object Serialization

While the text was in development, one of my friends pointed out that the title “file for objects” is incorrect. It should be “file of objects”. I politely pointed out that the use of word “for” was deliberate. What we have created was not the file of objects. He asked, “Is it because no strings?” (He was right in a way. Strings are also objects but they require unequal memory. The present model requires that every object must need the same number of bytes.) I replied, “No. The main reason is in that in this model we could not allow even reference!”

As mentioned earlier, there are two dynamic data structures, namely, linked list and binary tree. In these structures, it is possible for an object to refer to one or many objects. Those objects can refer to still more objects.

Hence, if we claim to store one object, we may have to store 100 objects with complex interlinking. This appears to be a very difficult task. But Java makes it amazingly simple. Java allows serialization of the object. It also allows us to simply call one particular write method. However, this topic is beyond the scope of this chapter.

17.11 End of Chapter Programs

17.11.1 Large binary file

It is a known fact that data stored in binary form is read very quickly. However, it is not possible to test the premise when we deal with small size files. In practice, files are of very large size in applications like databases. Hence, it will be a good idea to measure the time needed to read a large binary file.

Problem: Write a program to demonstrate reading of large binary files.

Solution: Let us first create a binary file storing 10,000,000 integers. Then we will read them back. For measuring time, we will use methods from class BPtimer (see Program 17.11).

 

PROGRAM 17.11 Large Binary File

 //         binfile12.java

 //    Creating LARGE Binary file

 import java.io.* ;

 class binfile12

   {   public static void main(String[] args) throws Exception

          {   int i,k=0;

              System.out.println("<---binfile12.java starts--->");

              FileOutputStream fx = new

                     FileOutputStream("binfile1.dat");

              BufferedOutputStream bos = new

              BufferedOutputStream(fx);

              DataOutputStream f2 = new DataOutputStream(bos);//(fx);

              for (i=1;i<=10000000;i++)

           // while( f2.ready() )

                 {   f2.writeInt(i);

                 }

              f2.close();

              System.out.println("file created successfully");

              FileInputStream fy = new

              FileInputStream("binfile1.dat");

              BufferedInputStream bis = new BufferedInputStream(fy);

              DataInputStream f1 = new DataInputStream(bis);//(fy);

              System.out.println("reading starts");

                 BPtimer.start();

              for (i=1;i<=10000000;i++)

                        k=f1.readInt();

              System.out.println("file read successfully");

              System.out.println(k + " ");

              f1.close();

              BPtimer.stop();

           }

   } ;

 class BPtimer

   {   private static long t0;

       private static long t1;

       public static void start()

           {  t0 = System.currentTimeMillis();

           }

       public static void stop()

           {  t1 = System.currentTimeMillis() - t0 ;

              System.out.println("time measured = " + t1

                 + " milliSeconds");

           }

 }

 

If you run this program, you will get the following output.

 

Output

 <---binfile12.java starts--->

 file created successfully

 reading starts

 file read successfully

 10000000

 time measured = 1063

   milliseconds

17.11.2 Large text file

We have just seen a large binary file. For comparison purpose, we are required to work with a large text file which will take much more time to read and write. Computer scientists have developed the concept of buffering (hardware) to reduce this time. Java offers us the classes BufferedReader and BufferedWriter for this purpose. Let us study it with help of a program.

Problem: Write a program to show that one can read faster with the help of BufferedReader.

Solution: To appreciate the speed, we must have a very large file. Here we will create a large text file and keep natural numbers from 1 to 10,000,000 in it (one number in one line). Then we will read this file. We will use methods from class BPtimer to measure the time (see Program 17.12).

 

PROGRAM 17.12 Large Text File

 //  big size text files

 //       fo4.java

 import java.io.* ;

 public class fo4

    {  public static void main(String[] args) throws Exception

           {  String s1 ;

              int i =10 ;

              int k =0;

              System.out.println("<---fo4.java--->");

              System.out.println("Creating Data file");

              FileWriter f2 = new FileWriter("fo4.dat");

              BufferedWriter bw = new BufferedWriter (f2) ;

                 for (i=1;i<=10000000;i++)

                    bw.write(i+ " " );

              bw.close();

              System.out.println("file fo4.dat created");

              FileReader f1 = new FileReader("fo4.dat");

              BufferedReader fin = new BufferedReader(f1);

              System.out.println("file reading starts");

              BPtimer.start();

                  while ( fin.ready() )

                  {   s1 = fin.readLine();

                      k=Integer.parseInt(s1);

                  }

           //         System.out.println(k); // for debugging

              fin.close();

              BPtimer.stop();

              System.out.println("program over");

           }

       } ;

 class BPtimer

   {   private static long t0;

       private static long t1;

       public static void start()

              {   t0 = System.currentTimeMillis();

              }

           public static void stop()

              {   t1 = System.currentTimeMillis() - t0 ;

                  System.out.println("time measured = " + t1 + " in milli seconds");

              }

 }

 

If we run this program, we will get the following output.

 

Output

 <---fo4.java--->

 Creating Data file

 file fo4.dat created

 file reading starts

 time measured = 5797

   in milli seconds

 program over

 

You may modify the program in such a way that BufferedReader is not used. Find the time to read in that case.

The contents of this text file were same as binary file of the previous program. Compare the time recorded in both the programs.

17.11.3 List of files

Problem: Write a program to find and list all the files in a given directory.

Solution: Java supports a very interesting method named list(). It gets all the names of all the files in the directory and put it in an array of string. See Program 17.13.

 

PROGRAM 17.13 Listing Files from a Directory

 //      file3.java

 import java.io.* ;

 class file3

   {   public static void main(String[] args) throws Exception

          {   int i, k ;

              String dname = new String("c:/jprog/ch17/file3");

              File d1 = new File( dname);

              String[] filelist ;

              System.out.println("<---file3.java starts--->");

              if( d1.isDirectory() )

                     System.out.println("Yes it is a directory");

                 else

                    {   System.out.println(

                               " File named is not a directory");

                        System.exit(0);

                    }

              filelist = d1.list();

              k = filelist.length;

              System.out.println("no of entries are " + k);

              for(i=0;i<k;i++)

                 System.out.println(i+") " + filelist[i] );

          }

 }

 

If you run this program, you will get the following output.

 

Output

 <---file3.java starts--->

 Yes it is a directory

 no of entries are 2

 0) file3.class

 1) file3.java

 

As expected, the program lists all the files in the specified directory. Unfortunately, this method also lists folders (directories) as files when they exist. It is left to the readers to improve the program such that the output contains only files and not the folders (directories).

17.11.4 Reading matrices from binary files

Problem: Write a program to read a matrix from a binary data file.

Solution: Earlier we solved a problem on 3 × 3 matrix addition. We will use the same program but will add a new constructor which will accept the file name as a parameter (see Program 17.14).

 

PROGRAM 17.14 Reading an Array from Binary File

 //       matrix3.java

 //    reading from binary file

 /        matrix addition

 import java.io.* ;

 class mat3x3

       {  int[][] ele = new int[3][3];

          mat3x3( int[] A )

              {  int i,j,k=0;

                 for(i=0;i<=2;i++)

                    for(j=0;j<=2;j++)

                       ele[i][j]=A[k++];

              }

           mat3x3()    // creates matrix without assigning values

           {

           };

           mat3x3(String fname) throws Exception

                  // creates matrix from file

           {  int i,j,k;

              FileInputStream fy = new

                      FileInputStream(fname);

                      DataInputStream f1 = new

                      DataInputStream(fy);

              System.out.println(“constructor invoked”);

              for(i=0;i<=2;i++)

                 for(j=0;j<=2;j++)

                    {   k=f1.readInt();

                        System.out.print(k + “ “); // for debugging only

                        ele[i][j] = k ;

                    }

                 System.out.println();

              fy.close();

           };

       }

 class matrix3

 {

   public static void main(String arg[]) throws Exception

       {  mat3x3 mat1 = new mat3x3(“mat1.dat”) ;

          mat3x3 mat2 = new mat3x3(“mat2.dat”) ;

          mat3x3 mat3 = new mat3x3();

          int i,j;

          System.out.println(“--->matrix3.java<---“);

 //       calculating

          for(i=0;i<=2;i++)

             for(j=0;j<=2;j++)

                mat3.ele[i][j] = mat1.ele[i][j] + mat2.ele[i][j];

          System.out.println(“mat1”);

          for(i=0;i<=2;++i)

             {   for(j=0;j<=2;++j)

                        System.out.print(“ ” + mat1.ele[i][j]);

                 System.out.println();

             }

          System.out.println(“mat2”);

          for(i=0;i<=2;++i)

             {  for(j=0;j<=2;++j)

                       System.out.print(“ ” + mat2.ele[i][j]);

                System.out.println();

             }

          System.out.println(“mat3”);

          for(i=0;i<=2;++i)

              {  for(j=0;j<=2;++j)

                    System.out.print(“ ” + mat3.ele[i][j]);

                 System.out.println();

              }

       }

 }

 

If you run this program, you will get the following output.

 

Output

constructor invoked

Note that line

“constructor invoked”

tells us that the constructor with file name as parameter is invoked.

17.11.5 Listing all the files including those in the sub-folders

File structure in most of the OSs is tree structure. We can see only one folder at a time. We cannot see or list all the files easily. Hence, an application which can list all the files in a given directory is highly desirable. Let us try our knowledge of files to do this task.

Problem: Write a program to find (using recursion) all the files in a given directory and all of its sub directories.

Solution: Writing a solution without recursion will be difficult. Recursion makes the program simple and short. In essence, we should develop a recursive method which gets all the files. Let us name such method as getThemAll (see Program 17.15).

 

PROGRAM 17.15 Listing all Files

 //    ftree3.java

 //    uses recursion to list all files.

 //

 import java.io.* ;

 class ftree3

   {   static File[] filelist ;

       static FileWriter f2;

       static int fileCount =0;

       static void getThemAll(File d1) throws IOException

           {  int i,k,dind;

              System.out.println("Yes it is a directory-> "+ d1);

              filelist = d1.listFiles();

              k = filelist.length;

              System.out.println("no of entries are " + k);

              File dirArray[] = new File[k] ;

              dind =0 ; // index for darray

              for(i=0;i<k;i++)

                  {  if(filelist[i].isDirectory() )

                         {   dirArray[dind++] = filelist[i] ;

                         }

                      else

                         {   System.out.println(fileCount + ") " + filelist[i] +" "+"file");

                             f2.write(fileCount + ") " + filelist[i] +" ");

                             fileCount++;

                         }

                  }

               for(i=0;i<dind;i++)

                  {  System.out.println( i + ") " + dirArray[i] );

                     getThemAll ( dirArray[i] );

                  }

    }

    public static void main(String[] args) throws Exception

        {  int i, k ;

           String dname = new String("C://Jprog");

           File d1 = new File( dname);

           f2 = new FileWriter("ftree3.out");

           System.out.println("<---ftree3.java starts--->");

           if( d1.isDirectory() == false)

              {   System.out.println(" File named is not adirectory");

                  return ;

              }

           getThemAll( d1);

           f2.close();

        }

 }

 

If you run this program, you will get the output on screen as well as stored in the file. When I ran this program, there were more than 12,000 lines in the output. Only the first few lines are presented in the following output.

 

Output

 0) C:JprogJXP7.bat

 1) C:JprogJXP6n.bat

 2) C:JprogcmdJdk6.bat

 3) C:JprogBPJA6new.bat

 4) C:JprogBPJA6N.EXE

 5) C:JprogxxBPJA6NEW.EXE

 6) C:JprogLatest Java_prog_list.txt

 7) C:JprogBPJA6N.PIF

 8) C:Jprogubgra1.class

 9) C:Jprogch3it1it1.class

 10) C:Jprogch3it1it1.java

 11) C:Jprogch3area1area1.class

 12) C:Jprogch3area1area1.ctxt

 13) C:Jprogch3area1area1.java

 14) C:Jprogch3area1luej.pkg

 15) C:Jprogch3area1luej.pkh

 16) C:Jprogch3char1char1.java

 17) C:Jprogch3char1char1.class

 18) C:Jprogch3char1char1.out

 19) C:Jprogch3char3char3.java

 20) C:Jprogch3char3char3.class

 21) C:Jprogch3char3char3n.class

 22) C:Jprogch3char3char3n.out

 23) C:Jprogch3char3char3n.java

 24) C:Jprogch3const1const1.java

 25) C:Jprogch3const1const1.class

 26) C:Jprogch3final1afinal1a.err

 27) C:Jprogch3final1afinal1a.java

 28) C:Jprogch3final1final1.java

 29) C:Jprogch3final1final1.class

 30) C:Jprogch3line1line1.java

 31) C:Jprogch3line1line1.class

 32) C:Jprogch3line1line1.out

 33) C:Jprogch3logical1logical1.java

 34) C:Jprogch3logical1logical1.class

 35) C:Jprogch3modulo1modulo1.java

 36) C:Jprogch3modulo1modulo1.class

 37) C:Jprogch3 elop1 elop1.java

 38) C:Jprogch3shift1shift1.java

 39) C:Jprogch3shift1shift1.class

 40) C:Jprogch3 runc1 runc1.java

 41) C:Jprogch3 runc1 runc1.class

 42) C:Jprogch3unicode1unicode1.class

 43) C:Jprogch3unicode1unicode1.java

 44) C:Jprogch3firstabc1.doc

 45) C:Jprogch3firstfirst.class

 46) C:Jprogch3firstfirst.java

 47) C:Jprogch3firstfirst.out

 48) C:Jprogch3unicode2unicode2.out

 49) C:Jprogch3unicode2unicode2.java

 50) C:Jprogch3unicode2unicode2.class

 

If you study the output, you will find that this program first lists all the files from a given directory namely C:Jprog. Then it prints files in the sub-directories also.

Keywords

absolute pathname, abstract pathname, binary files, BufferedReader, BufferedWriter, canRead(), canWrite(), class File, DataInputStream, DataOutputStream, delete(), deleteOnExit(), direct access file, exists(), FileInputStream, FileNotFoundException, FileOutputStream, Format-free data, formatted data, getAbsoluteFile(), getAbsolutePath(), getParent(), getParentFile(), input file, isAbsolute(), lastModified(), list(), listFiles(), mkdir(), object serialization, output file, random access files, record, sequential access file, text files.

Review Questions

  1. What are the various ways of classifying files?
  2. What are the advantages of binary file?
  3. What are the advantages of text files?
  4. What are the advantages of random access files?
  5. What is object serialization?
  6. What is the use of class StringTokenizer?
  7. What is the difference between abstract pathname and absolute pathname?

Exercises

  1. Write a program to read your name, roll number, address, and marks obtained in physics, chemistry, and mathematics from keyboard and place it in file.
  2. Write a program to read the biodata of 20 applicants and write them to a file.
  3. Write a program to display a specified text file on console. Assume that the file is specified as command line argument. (Hint: show only 20 lines at a time.)
  4. Assume that a data file is a text file. Write a program that will read integer n, and display the nth line on the screen.
  5. Write a program to encrypt and decrypt files.
  6. Write a program to generate directory of colleges in Mumbai city. The entries must be the name of the college, telephone number, and the degree offered. Allow interactive data entry and retrieval.
  7. Write a program that finds and print the total number of characters and total number of words in a text file. The program should ask the user to enter the name of file.
  8. Write a program to display the mobile number of your classmates when you enter his roll number. Assume that the roll numbers are starting from 601. Assume that the data is stored in a random access file.
  9. Repeat the aforementioned program for whole institute. Assume that there are about 1,500 students. Roll numbers start from 1 and end at 3,999. (Naturally, all the roll numbers are not assigned.)
  10. Write a Java program for counting the number of characters, words, and lines in a file.
  11. Write a program to create a data file containing the following information.
The information should be entered using console.

The information should be entered using console.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.101.81