Strings and File IO


File IO

Content modified from the Java Tutorials at http://java.sun.com/docs/books/tutorial/essential/io/index.html

Input and Output Streams

The java.io package provides input and output streams that enable the programmer to read data from and write data to various sources. Unsurprisingly, the FileInputStream class allows the programmer to read data, in bytes, from a file. This is useful for processing images or other non-textual information. However, FileReader is significantly more useful for processing text as it enables you to read data a character at a time from a file. Still, this can be cumbersome. BufferedReader provides even more functionality, supporting a readLine operation that retrieves and returns the next line of text from the file. Similarly, the FileWriter class allows you to write data to a file a character at a time, while the PrintWriter supports the println operation, the same method you call when you output text to the standard output (e.g., System.out.println("Hello")),

Take a look at the CopyLines class provided in the Java tutorial. Notice the following:

Importing the java.io Package

In order to use the classes provided in the java.io package, you must import them. CopyLines imports only the classes it needs. Recall that using "*" (e.g., import java.io.*;) will import all of the classes in a particular package.

Wrapping Streams

Creating input and output streams requires several steps. In order to create a BufferedReader, you must first create a FileReader passing the FileReader constructor the name of the file you'd like to open. You then pass the FileReader to the BufferedReader constructor. Similarly, the PrintWriter constructor takes as input a FileWriter, the constructor of which takes as input a file name.

Exceptions

The header of the main method includes throws IOException. Instantiating new Reader and Stream objects, as well as invoking methods to read and write data, all may result in an exceptional situation. For example, the file you attempt to open may not be found, or the file you attempt to read from may be empty. In these cases, an exception is thrown. The CopyLines class simply propagates the exception to the caller of the main method, which is the runtime system in this case. You could also catch the exception in the main method (as shown below) and perform an appropriate action.

try {            
	inputStream = new BufferedReader(new FileReader("xanadu.txt"));            
	outputStream = new PrintWriter(new FileWriter("characteroutput.txt"));            
	String l;            
	while ((l = inputStream.readLine()) != null) {                
		outputStream.println(l);            
	}
} catch(IOException ioe) {
	//do something appropriate like print a message
} finally {
	if (inputStream != null) {                
		try {
			inputStream.close();            
		} catch(IOException ioe) {
			//do something appropriate
		}
	}            
	if (outputStream != null) {                
		outputStream.close();            
	}
}

Closing the File/Finally

The example above illustrates the use of the finally clause. The finally clause always executes, regardless of whether an exception is thrown. If no exception is thrown, all of the try part will execute, followed by the finally clause. If an exception is thrown, the try part will execute until the exception is thrown, the catch part will execute, and then the finally part will execute. The finally is quite commonly used to clean up after file IO. In this case, it ensure that the files are closed whether an exception was thrown or not.

Relative and Absolute Paths

The example above uses relative paths. In this case, the program will look in the directory where the program is located to find the files. Similarly, if we replaced "xanadu.txt" with "text_files/xanadu.txt", the program would look in the test_files directory of the current directory and attempt to locate the file xanadu.txt.

Alternatively, we could use absolute path names. On a unix system, that would look something like this: "/home/srollins/cs112-f08/myfile.txt”. On a windows system, it would look something like this: “C:\\srollins\\cs112-f08\\myfile.txt”

Random tip: Never use spaces in your file or directory names.


Strings

Content modified from the Java Tutorials at http://java.sun.com/docs/books/tutorial/java/data/strings.html

Fundamentally, a String is a sequence of characters. The String class provides various methods to access portions of a String, but recall that Strings are immutable. That means that they do not change. To morph one String into another, you must use methods to create a new String object containing the new set of characters.

Common Methods

Following are several common methods that are fairly self-explanatory. Take a look at the String API for a bit more detail.

The split Method

The split method can be used to divide a String into several substrings. It takes as input a regular expression denoting the how the string should be split and returns an array of Strings. In the simplest case, the expression is a character denoting the delimiter to be used. The following example splits the String around the space character. The result is an array of Strings where each string is one word of the original string. Note that the delimiter is removed from the result.

String theString = "This is the test string";
String[] theSplitString = theString.split(" ");

Exercises:

  1. Modify the code above such that the split method will produce the array ["Thi", "i", "the test string"]

Sami Rollins

Date: 2007-08-10