|
![]() |
![]() |
![]() |
![]() |
The process for reading a file parallels that of writing a file. You obtain a FileChannel object from a file from a file stream, and use the channel to read data from the file into one or more buffers. Initially we will be using a channel object from a FileInputStream object to read a file. Later when we want to read and write the same file we will be using a FileChannel object obtained from a RandomAccessFile object. Like the FileOutputStream class, the FileInputStream class defines its own methods for file input, as does the RandomAccessFile class. However, we will completely ignore these because the file channel methods for reading the file are much more efficient and will eventually obsolete the stream methods. In any event, if you are curious to see how the old stream input mechanism works you can find details of the methods that read from a file stream in the descriptions for the FileInputStream and RandomAccessFile classes in the documentation that accompanies the SDK.
The starting point for reading a file is to create a FileInputStream object. Creating FileInputStream objects is not very different from creating FileOutputStream objects so let's look into how we do that first.
Important |
In our examples in this chapter we will be reading some of the files that we created in the last chapter so I hope that you kept them. |
Since a FileInputStream object encapsulates a file that is essentially intended to be read and therefore must contain some data, a constructor for this class can only create an object for a file that already exists. There are three constructors for FileInputStream objects, each of which takes a single argument.
First of all you can create a FileInputStream object from a String object that specifies the file name. For example:
FileInputStream inputFile = null; // Place to store the input stream reference try { inputFile = new FileInputStream("C:/Beg Java Stuff/myFile.txt"); } catch(FileNotFoundException e) { e.printStackTrace(System.err); System.exit(1); }
The try block is necessary here because this constructor will throw a FileNotFoundException if the file does not exist or the argument to the constructor specifies a directory rather than a file.
You could also use a File object to identify the file, like this:
File aFile = new File("C:/Beg Java Stuff/myFile.txt"); FileInputStream inputFile = null; //Place to store the input stream reference try { inputFile = new FileInputStream(aFile); } catch(FileNotFoundException e) { e.printStackTrace(System.err); System.exit(1); }
This constructor can also throw a FileNotFoundException so again we must create the FileInputStream object within a try block. Using a File object to create a FileInputStream object is the preferred approach because you can check that the file exists before creating the stream and thus avoid the possibility of throwing a FileNotFoundException.
The third possibility is to use a FileDescriptor object that you have obtained by calling the getFD() method for an existing FileInputStream object, or possibly a RandomAccessFile object. For example:
File aFile = new File("C:/Beg Java Stuff/myFile.text"); FileInputStream inputFile1 = null; // Place to store an input stream reference FileDescriptor fd = null; // Place to store the file descriptor try { // Create the stream opened to write inputFile1 = new FileInputStream(aFile); fd = inputFile1.getFD(); // Get the file descriptor for the file } catch(IOException e) { // For IOException or FileNotFoundException e.printStackTrace(System.err); System.exit(1); } // We can now create another input stream for the file from the file descriptor... FileInputStream inputFile2 = new FileInputStream(fd);
The getFD() method can throw an exception of type IOException if an I/O error occurs. Since IOException is a superclass of FileNotFoundException, the catch block will catch either type of exception.
I'm sure that you noticed that the constructor call that creates inputFile2 is not in a try block. This is not an oversight. When you create the FileInputStream object from a FileDescriptor object, the FileNotFoundException cannot be thrown since a FileDescriptor object always refers to an existing file. This is because a FileDescriptor object can only be obtained from a file stream object that already encapsulates a connection to a physical file so there can be no doubt that the file is real.
As with the FileOutputStream constructors, any of the FileInputStream constructors will throw a SecurityException if a security manager exists on the system and read access to the file is not permitted. Since this is a type of RuntimeException you don't have to catch it.
![]() |
![]() |
![]() |