440 likes | 596 Views
File input and output. Interactive vs. file I/O. All of the programs we have seen or written thus far have assumed interaction with a user, who types in data at a keyboard and sees output on a screen We can also receive data from, or send data to, the secondary storage devices on the computer
E N D
Interactive vs. file I/O • All of the programs we have seen or written thus far have assumed interaction with a user, who types in data at a keyboard and sees output on a screen • We can also receive data from, or send data to, the secondary storage devices on the computer • This type of input and output is called file I/O
File I/O • The action of saving, or writing, data to a file is called file output. • The action of reading data from a file is called file input. • Both of these actions involve interacting with the operating system and its file structure
The file concept • We can envision a file as a special kind of container that can hold a collection of data or instructions • A file can also contain a collection of other files: such a file is called a directory or folder • An important point to remember is that Java considers a folder to be just another file
File system organization • Under Windows and most other modern operating systems, information is stored on disk in a hierarchically ordered structure consisting of directories, subdirectories, and files • Disks are designated using letters – for example, C is typically the computer’s hard drive (or its primary partition), while A is traditionally a floppy disk • The Windows GUI portrays directories as folders, which can contain other folders or files
Windows file system example The illustration below depicts a typical file system structure under Windows
Opening a file for input or output • Before we can read data from a file, we must create a File object and associate it to the file from which we wish to read. • When a valid association is established, we say a file is opened. • A file must be opened before we can do any input and output to the file. • We do this by calling a File constructor
Opening a file • The simplest syntax for opening a file is: File aFile = new File (“filename”); • The String argument designates the name of the file (as seen by the operating system) • This syntax assumes that the argument is the name of a file (not a folder), and that the file is located in the same folder as the program’s code file
Opening a file • Slightly more complicated syntax is necessary if the file to be opened is in a different folder: File aFile = new File (“path”, “file”); • The first argument specifies the disk and file system hierarchy that contains the file • For example, if the file is in directory G:\shared\cate\cs1, you would write: File aFile = new File (“g:/shared/cate/cs1”, “file”); Note the use of the forward slash; you can use either this format or: File aFile = new File (“g:\\shared\\cate\\cs1”, “file”);
Opening a file • A File object may also be associated to a directory. • As far as Java is concerned, a directory is just a special kind of file • The code on the next slide illustrates the use of a File object to open a directory, then list the names of all the files in the directory
Example • File directory = new File (“C:/JavaPrograms/Ch12”); • String filename[] = directory.list(); • // Returns an array of strings naming the files and • // directories in the directory denoted by this pathname • for (int i=0; i<filename.length; i++){ • System.out.println(filename[i]); • }
File methods • The previous slide illustrated the use of the list() method, which returns an array of Strings containing the names of files within a directory • Several other useful methods of the File class are listed in the Java API; we will examine a few of these
File methods • We can check if a File object is associated correctly to an existing file by calling its exists method: if (inFile.exists()) { // inFile is associated correctly to an existing file } else { // inFile is not associated to any existing file } • It is particularly useful to check input files to see if they actually exist before we try to read from them
File methods • To determine if a File object is associated to a file or directory, we call its boolean method isFile. • A similar method, isDirectory, returns true if the File object is associated with a folder instead of an ordinary file.
Choosing a file from a list • A javax.swing.JFileChooser object allows the user to select a file from a list of available files. • The code fragment below illustrates how this is done: JFileChooser chooser = new JFileChooser(); ... chooser.showOpenDialog(null);
A JFileChooser object displayed with the showOpenDialog method
JFileChooser Object methods • The getSelectedFile method retrieves the desired file. • The getName and getAbsolutePath methods retrieve the name and full path of a selected file (similar methods exist for File objects). • The showSaveDialog method displays a JFileChooser with a Save button.
A JFileChooser object displayed with the showSaveDialog method
JFileChooser Example • The next couple of slides display a program that uses JFileChooser objects to display a list of files, then allow the user to choose which file should be open for output • Note the use of File and JFileChooser methods in the code
import java.io.*; import javax.swing.*; public class TestJFileChooser { public static void main (String[] args) { JFileChooser chooser; File file, directory; int status; chooser = new JFileChooser( ); status = chooser.showOpenDialog(null); if (status == JFileChooser.APPROVE_OPTION) { file = chooser.getSelectedFile(); directory = chooser.getCurrentDirectory(); System.out.println("Directory: " + directory.getName()); System.out.println("File selected to open: " + file.getName()); System.out.println("Full path name: " + file.getAbsolutePath()); } else { JOptionPane.showMessageDialog(null, "Open File dialog canceled"); }
System.out.println("\n\n"); status = chooser.showSaveDialog(null); if (status == JFileChooser.APPROVE_OPTION) { file = chooser.getSelectedFile(); directory = chooser.getCurrentDirectory(); System.out.println("Directory: " + directory.getName()); System.out.println("File selected for saving data: " + file.getName()); System.out.println("Full path name: " + file.getAbsolutePath()); } else { JOptionPane.showMessageDialog(null, "Save File dialog canceled"); } } }
Reading and Writing Files • Once a file is opened by associating a File object to it, we can access the file. • To read data from or write data to a file, we must create one of the Java stream objects and attach it to the file. • A stream is a sequence of data items, usually 8-bit bytes. • Java has two types of streams: an input stream and an output stream.
Reading and Writing Files • An input stream has a source from which the data items come, and an output stream has a destination to which the data items are going. • FileOutputStream and FileInputStream are two stream objects that facilitate file access. • FileOutputStream allows us to output a sequence of bytes; values of data type byte.
Writing Data to a File • To send output to a file, do the following: • Create and open a File object File output = new File(“C:/datafiles”, “stuff”); • Associate a new FileOutputStream object with the File object FileOutputStream outs = new FileOutputStream(output); • Write the desired data to the FileOutputStream object byte [] snacks = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; outs.write(snacks); • Close the File stream outs.close();
The importance of closing a file • If the stream object is not closed, then data may get lost due to data caching • Data is saved in blocks of bytes to reduce the time it takes to save all of our data. • The operation of saving data as a block is called data caching. • To carry out data caching, part of memory is reserved as a data buffer or cache, which is used as a temporary holding place.
The importance of closing a file • Data are first written to a buffer. When the buffer becomes full, the data in the buffer are actually written to a file. • If there are any remaining data in the buffer and the file is not closed, those data will be lost.
Reading Data from a File • To read data into a program, we reverse most of the steps in the output routine. • We use the read method of FileInputStream to read in an array of bytes. • First we create a FileInputStream object: File inFile = new File(“sample1.data”); FileInputStream inStream = new FileInputStream(inFile); • Then we must declare and create an array to hold the data: int filesize = (int) inFile.length(); byte[] byteArray = new byte[filesize];
Reading Data from a File • We use the length method of the File class to determine the size of the file. • This allows us to create an array of bytes whose size is the size of the file. • Finally, we read the data into the array of bytes: inStream.read(byteArray);
Low-level File I/O • The read and write methods of the FileInputStream and FileOutputStream classes read and write entire arrays of bytes, as we have seen • We can output data other than bytes if we can type cast them into bytes. • To read the data back, we use the read method. • Depending on the data type we converted the data from, we may need to type cast back into the original data type.
High-level File I/O • Using DataOutputStream allows us to output Java primitive data type values by converting the values into a sequence of bytes. • The argument to the DataOutputStream constructor is a FileOutputStream object. • A DataOutputStream object does not get connected to a file directly; instead, its role is to provide high-level access to a file by handling the data type conversions.
High-Level File I/O • To read data back from the file, we reverse the operation. • We use three objects: File, FileInputStream, and DataInputStream. • Data must be read in the order in which it was written; otherwise, the results will be unpredictable.
High-Level File I/O • FileOutputStream and DataOutputStream objects produce a binary file in which the contents are stored in the format (binary format) in which they are stored in the main memory. • Data may be stored in ASCII format instead of binary format – this requires the use of a different set of objects
High-Level File I/O • With ASCII format, all data are converted to string data. • A file whose contents are stored in ASCII format is called a text file. • Togenerate a textfile we use a PrintWriter is an object . • PrintWriter supports only two output methods, which should look familiar: • print • println (for print line)
High-Level File I/O • An argument to the methods may be any primitive data type. • The methods convert the parameter to string and output this string value. • The constructor of PrintWriter, like that of DataOutputStream, requires an output stream as its argument.
High-Level File I/O • To read data from a text file, we use the FileReader and BufferedReader objects. • We first associate a BufferedReader object to a file. File inFile = new File(“sample3.data”); FileReader fileReader = new FileReader(inFile); BufferedReader brdr = new BufferedReader(fileReader); • Then we read data, using the readLine method of BufferedReader. String str = bufReader.readLine(); • Finally, we convert the String to a primitive data type as necessary (using wrapper classes as we’ve done before).
File I/O and Objects • To write objects to a file, we use ObjectOutputStream. • To read objects from a file, we use ObjectInputStream.
File I/O and Objects • In this example, we will write Person objects to a file. • The first step is to modify the Person class definition to allow ObjectOutputStream and ObjectInputStream to perform object I/O. • We modify the definition by adding the phrase implements Serializable to it. import java.io.*; class Person implements Serializable { // the rest is the same }
File I/O and Objects • To save objects to a file, we first create an ObjectOutputStream object: File outFile = new File(“objects.dat”); FileOutputStream outFileStream = new FileOutputStream(outFile); ObjectOutputStream outObjectStream = new ObjectOutputStream(outFileStream);
File I/O and Objects • To save a Person object, we execute: Person person = new Person(“Mr. Man”, 20, ‘M’); outObjectStream.writeObject (person); • Different types of objects may be saved to a single file. • We can also mix objects and primitive data type values in the same file.
File I/O and Objects • To read objects from a file, we use FileInputStream and ObjectInputStream. • We use the method readObject to read an object. • Because we can store any types of objects to a single file, we must type cast the object read from the file.
File I/O and Objects • The readObject method can throw a ClassNotFoundException (wrong type casting) in addition to an IOException. • Either exception may be caught or propagated. • If a file contains objects from different classes, they must be read in the correct order and the matching type casting must be applied.