File Navigation and I/O
- Details
- Category: Programming Guides & Tutorials
- Published on Tuesday, 05 February 2013 06:02
- Written by Vinayaga Moorthy
I/O is a huge topic in general, and the Java APIs that deal with I/O in one fashion or another are correspondingly huge. A general discussion of I/O could include topics such as file I/O, console I/O, thread I/O, high-performance I/O, byte-oriented I/O, character-oriented I/O, I/O filtering and wrapping, serialization, and more.
Here's a summary of the I/O classes you'll need to understand for now:
1. File The API says that the class File is "An abstract representation of file and directory pathnames." The File class isn't used to actually read or write data; it's used to work at a higher level, making new empty files, searching for files, deleting files, making directories, and working with paths.
2. FileReader This class is used to read character files. Its read() methods are fairly low-level, allowing you to read single characters, the whole stream of characters, or a fixed number of characters. FileReaders are usually wrapped by higher-level objects such as BufferedReaders, which improve performance and provide more convenient ways to work with the data.
3. BufferedReader This class is used to make lower-level Reader classes like FileReader more efficient and easier to use. Compared to FileReaders, BufferedReaders read relatively large chunks of data from a file at once, and keep this data in a buffer. When you ask for the next character or line of data, it is retrieved from the buffer, which minimizes the number of times that time-intensive, file read operations are performed. In addition, BufferedReader provides more convenient methods such as readLine(), that allow you to get the next line of characters from a file.
4. FileWriter This class is used to write to character files. Its write() methods allow you to write character(s) or Strings to a file. FileWriters are usually wrapped by higher-level Writer objects such as BufferedWriters or PrintWriters, which provide better performance and higher-level, more flexible methods to write data.
5. BufferedWriter This class is used to make lower-level classes like FileWriters more efficient and easier to use. Compared to FileWriters, BufferedWriters write relatively large chunks of data to a file at once, minimizing the number of times that slow, file writing operations are performed. In addition, the BufferedWriter class provides a newLine() method that makes it easy to create platform-specific line separators automatically.
6. PrintWriter This class has been enhanced significantly in Java 5. Because of newly created methods and constructors (like building a PrintWriter with a File or a String), you might find that you can use PrintWriter in places where you previously needed a Writer to be wrapped with a FileWriter and/or a BufferedWriter. New methods like format(), printf(), and append() make PrintWriters very flexible and powerful.
Stream classes are used to read and write bytes, and Readers and Writers are used to read and write characters. Since all of the file I/O now is related to characters, if you see API class names containing the word "Stream", for instance DataOutputStream, then the question is probably about serialization, or something unrelated to the actual I/O objective.
Creating Files Using Class File
Objects of type File are used to represent the actual files (but not the data in the files) or directories that exist on a computer's physical disk. Just to make sure we're clear, when we talk about an object of type File, we'll say File, with a capital F. When we're talking about what exists on a hard drive, we'll call it a file with a lowercase f (unless it's a variable name in some code). Let's start with a few basic examples of creating files, writing to them, and reading from them. First, let's create a new file and write a few lines of data to it:
import java.io.*;
class Writer1 {
public static void main(String [] args) {
File file = new File("fileWrite1.txt"); // There's no file yet!
}
}
If you compile and run this program, when you look at the contents of your current directory, you'll discover absolutely no indication of a file called fileWrite1.txt. When you make a new instance of the class File, you're not yet making an actual file, you're just creating a filename. Once you have a File object, there are several ways to make an actual file. Let's see what we can do with the File object we just made:
import java.io.*;
class Writer1 {
public static void main(String [] args) {
try { // warning: exceptions possible
boolean newFile = false;
File file = new File("fileWrite1.txt"); // it's only an object
System.out.println(file.exists()); // look for a real file
newFile = file.createNewFile(); // maybe create a file!
System.out.println(newFile); // already there?
System.out.println(file.exists()); // look again
} catch(IOException e) { }
}
}
This produces the output
false
true
true
And also produces an empty file in your current directory. If you run the code a second time you get the output
true
false
true
Let's examine these sets of output:
1. First execution The first call to exists() returned false, which we expected…remember new File() doesn't create a file on the disk! The createNewFile() method created an actual file, and returned true, indicating that a new file was created, and that one didn't already exist. Finally, we called exists() again, and this time it returned true, indicating that the file existed on the disk.
2. Second execution The first call to exists() returns true because we built the file during the first run. Then the call to createNewFile() returns false since the method didn't create a file this time through. Of course, the last call to exists() returns true.
A couple of other new things happened in this code. First, notice that we had to put our file creation code in a try/catch. This is true for almost all of the file I/O code you'll ever write. I/O is one of those inherently risky things. We're keeping it simple for now, and ignoring the exceptions, but we still need to follow the handleor- declare rule since most I/O methods declare checked exceptions. We'll talk more about I/O exceptions later. We used a couple of File's methods in this code:
1. boolean exists() This method returns true if it can find the actual file.
2. boolean createNewFile() This method creates a new file if it doesn't already exist.
Remember, now creators are trying to jam as much code as they can into a small space, so in the previous example, instead of these three lines code,
boolean newFile = false;
...
newFile = file.createNewFile();
System.out.println(newFile);
You might see something like the following single line of code, which is a bit harder to read, but accomplishes the same thing:
System.out.println(file.createNewFile());
blog comments powered by Disqus
More 

