Interacting with Files - Java eLearning Kit For Dummies (2014)

Java eLearning Kit For Dummies (2014)

Chapter 12. Interacting with Files

· Locate and interact with files and directories on a hard drive by using the features of the java.io.File class.

· Open files so that you can read file content and interact with it.

· Write data to files as needed to update the file content and create new files.

· Use temporary files as needed to write data to disk while the application runs and then remove it when the application ends.

lingo_fmt.tif

1. How do I locate directories on a computer system using Java?

Java provides a number of path-specific features in the java.io.File class, such as the getPath() method, as shown on page 362

2. What sorts of information about files can I obtain?

Java provides access to all sorts of information about files, such as the last modification date and whether or not the file is hidden, (collectively known as the file attributes) as described on page 368

3. Is it possible to quickly determine whether an object is a file or a directory?

Yes, it is possible to separate files from directories in a list of entries by calling the isFile() method. To detect directories, you would use the isDirectory() method, as shown on page 368

4. Does Java let me append content to existing files?

It’s possible to overwrite a file or append new data to it, depending on how you open the file for writing, as shown on page 376

5. Why would I ever use temporary files?

Using temporary files makes it possible to perform disk operations in an application and then allow automatic cleanup of the file used for those operations, as explained on page 379

All of the applications in this book to date rely on computer memory to perform tasks. Computer memory is a kind of temporary storage. When you turn the computer off, the memory is gone. However, another sort of memory exists — files on disk. These files are more permanent in nature. If you don’t specifically delete a file (or the system deletes it for you), the file continues to exist on disk (with the exception of some major calamity such as a disk crash). The permanent memory provided by files lets applications pick up where they left off between computer sessions. Files also hold the data you want to work with in some way.

This chapter helps you discover the techniques used to locate, read, and write files on the hard drive. By knowing these techniques, you can move forward in learning how to locate, read, and write files from other data sources, such as the network. Working with files is a first step into entering a new world of data that this book hasn’t previously discussed.

Interacting with the File System

It doesn’t matter whether you’re using a Macintosh, Linux, or Windows computer — every operating system has some sort of file system associated with it. Yes, differences between file systems exist, but even so, the basic concepts are the same. A file is stored in a specific location on the drive, and if you know that location, you can read and write the file.


LINGO

A file is a storage container for data. Files can use a number of methods to hold and organize the data. Some of these organizational methods are easily readable by humans (such as text files), but others aren’t (such as graphics files).


Most operating systems rely on a hierarchical storage structure that relies on directories of files. Essentially, a directory is simply a container used to store files and other directories.


LINGO

A directory is a storage container for both directories (called subdirectories) and files. The directory is associated with the operating system’s file structure. It’s usually hierarchical.


The location of the directory on disk is called the path. A path normally begins at the uppermost point of the drive hierarchy, called the root node in most operating systems, and works its way down. For example, a path of C:\ would be the root node on the C drive. The Temp directory located within the root node would have a path of C:\Temp.


LINGO

A path is a description of the location of a particular directory or file on the hard drive. An absolute path starts with the drive and the root node of the drive and then works its way down to the specific directory or file. Most operating systems also support relative paths that define the location of a directory or file based on the current location in the directory hierarchy. The “Accessing the Java executables” section of Chapter 1 describes how to create paths on various platforms (Macintosh, Linux, Solaris, and Windows), so you can see how paths differ on various systems.


Some operating systems allow the use of relative paths. A relative path describes the location of a directory or file based on the current location. Using relative paths can be tricky and won’t be explored in this chapter.

A final path designation is the current path — the current location within the hierarchy. Most Java applications rely on the application directory as the current path (sometimes also called the default path). Most of the applications in this chapter rely on the current location in the interest of simplicity. In addition, using the current location means that the applications will work equally well on Linux, Macintosh, and Windows systems, which is one of the goals for this book.


GO ONLINE

File systems vary among the operating systems. In addition, learning absolutely everything about a file system could require an entire book. Most applications you write using Java can rely on an absolute path or the current path. However, you’ll want to know as much as possible about the file system.

Macintosh users have a variety of sources at their disposal. For hardcore technical information, you can rely on the Apple documentation on sites, such as http://support.apple.com/kb/TA27115. If you just want to know how paths work, check out the much easier tutorial at http://www.westwind.com/reference/OS-X/paths.html. You can also find an interesting comparison of Macintosh and Windows paths at http://www.zeusprod.com/technote/filepath.html.

The Macintosh and Linux operating systems are both strongly based on UNIX principles. Consequently, it won’t surprise you to discover that once you know how the Macintosh file system works, you also have considerable knowledge about the Linux file system. You can find a good description of the Linux file system and how it contrasts with Windows at http://www.freeos.com/node/36. A more technical description of the Linux file system appears at http://tldp.org/LDP/Linux-Filesystem-Hierarchy/html.

There are many misconceptions about the Windows file system. The only one of importance for this book is that you must use the backslash when working with Windows paths. It turns out that the forward slash works just as well in most cases (with some exceptions) because Windows, like the Macintosh and Linux file systems, has some basis in UNIX. Part of the problem with Windows is that it has had many file systems over the years, including File Allocation Table (FAT); New Technology File System (NTFS), which is covered at http://technet.microsoft.com/library/cc766145.aspx; and now, in Windows 8, the Resilient File System (ReFS), explained at http://blogs.msdn.com/b/b8/archive/2012/01/16/building-the-next-generation-file-system-for-windows-refs.aspx. All these file systems work essentially the same way at the command line, which is where you’ll be working with applications in this particular chapter. You can find a good resource for Windows developers at http://www.westga.edu/its/index_5327.php.


The following sections describe some of the ways in which you can access directories and paths using Java. You’ll also discover techniques for getting more info about these objects in the file system, such as whether or not a file is hidden.

Managing directory information

As previously mentioned, a directory is a kind of container used to hold files and other directories. A directory within the current directory is always called a subdirectory. The directory that holds the files and subdirectories is called the parent directory. The following example demonstrates a technique for listing the content of a directory so you know what files and subdirectories it contains.

Files needed: ListContent.java

1. If necessary, create the directory you plan to use for this example.

When working with the downloadable source code, you can find this example in the Chapter 12 directory.

2. Using a technique appropriate for your operating system, change directories to the example directory.

3. Using a technique appropriate for your operating system, create two directories in the current application directory: Test1 and Test2.

The downloadable source code already includes this addition.

4. Using a technique appropriate for your operating system, create a text file: MyText.txt. Make sure MyText.txt contains some content.

The downloadable source code already includes this addition, which contains the string "Content from a file!"

5. Open the editor or IDE that you’ve chosen to use for this book.

6. Type the following code into the editor screen.

// Import the required API classes.
import java.io.File;

public class ListContent
{
public static void main(String[] args)
{
// Create an object that holds the current 

// directory.
File Dir = new File(".");

// Obtain a list of child entries in the 

// directory.
String[] Children = Dir.list();

// List the name of each child.
for (String Child : Children)
System.out.println(Child);
}
}

The example begins by creating a File object, Dir. Even though it’s counterintuitive, the File object can refer to either a file or a directory. Later examples will demonstrate how to detect the difference. For now, all you need to know is that a File object can contain either object type.

remember.eps When working with a File object, you must define the location of the file or the directory. Providing an input string that has only a period (.) tells Java to use the current directory. This is a similarity in all three operating systems used for this book — a period always tells the operating system that you want to use the current directory.

The next step is to call the list() method, which returns a String[], Children, that contains one string for each file or directory in the current location. In this case, the example relies on a for-each loop to display the name of each Child in Children.

7. Save the file to disk using the filename ListContent.java.

8. In your command prompt, type javac ListContent.java and press Enter.

The compiler compiles your application and creates a .class file from it.

9. Type java ListContent and press Enter.

The application displays the content of the current directory, as shown in Figure 12-1. Notice that the output contains the ListContent source file, ListContent.java, the ListContent.class file, and the three additions you made earlier. (If you’re using the downloadable source rather than creating the files from scratch, your listing will contain all of the files and directories for the chapter.)

9781118098783-fg1201.tif

Figure 12-1:

Interacting with files

Files act as containers for data. In most cases, you search directories for the particular file that contains the data needed by an application. After the search is complete, you interact with the files in various ways to use and modify the data the files contain. In the following example, you create an application that ignores other directory entries (doesn’t print them) and prints the names of the files contained in the current directory.

Files needed: ShowFiles.java

1. Open the editor or IDE that you’ve chosen to use for this book.

2. Type the following code into the editor screen.

// Import the required API classes.
import java.io.File;

public class ShowFiles
{
public static void main(String[] args)
{
// Create an object that holds the current 

// directory.
File Dir = new File(".");

// Obtain a list of child entries in the 

// directory.
String[] Children = Dir.list();

// Check each entry for a filename.
for (String Child : Children)
{
// Create a File object for the child.
File ChildFile = new File(Child);

// Determine whether the child is a file.
if (ChildFile.isFile())
{
// Display the filename.
System.out.println(ChildFile.getName());
}
}
}
}

This example is an extension of the ListContent application. It begins by creating the File object, Dir, to interact with entries in the current directory. However, in this case, instead of listing every Child in Children, the code uses Child to create a File object, ChildFile.

remember.eps When you create a File object that uses just a filename for the argument, Java looks in the current directory for that file. If you want to look for a file in a different location, you must provide a path to find the file.

To determine whether ChildFile refers to a file, the code calls the isFile() method. This method returns true when the File object contains a file. When ChildFile does refer to a file, the example calls ChildFile.getName() to obtain the name of the file and display it onscreen.

3. Save the file to disk using the filename ShowFiles.java.

4. In your command prompt, type javac ShowFiles.java and press Enter.

The compiler compiles your application and creates a .class file from it.

5. Type java ShowFiles and press Enter.

The application displays only the files in the current directory, as shown in Figure 12-2. (If you’re using the downloadable source rather than creating the files from scratch, your listing will contain all of the files for the chapter.)

9781118098783-fg1202.tif

Figure 12-2:


EXTRA INFO

Java 8 provides new functionality for working with file listings. The Files.list(), Files.walk(), and Files.find() methods (all part of the java.nio.file.Files package) all return Stream objects (part of the java.util.stream package) that you can use to learn more about the file system. Use the list() method to obtain a listing of the specified directory, the walk() method to obtain information about the file system starting at a specific point in the listing, and the find() method to locate files that match the specification you provide. You can read more about these functions at http://download.java.net/jdk8/docs/api/java/nio/file/Files.html. The Stream object documentation appears athttp://download.java.net/jdk8/docs/api/java/util/stream/BaseStream.html.


Defining file and directory attributes

Both files and directories have attributes. One of these attributes determines whether the object is a file or a directory — the ShowFiles example demonstrates how to use this attribute to separate files from directories in the list of entries (by calling isFile()). There’s a similarisDirectory() method you can use to detect directories. However, files and directories provide a wealth of other attributes that help you determine how to interact with them.


LINGO

File systems rely on attributes to determine how to interact with files and directories. For example, an attribute can determine whether a file is readable, writeable, or both. Special attributes can tell you when a file or directory was last modified. In short, attributes help you understand file and directory entries better.


By using the file and directory attributes carefully, you can create robust applications that don’t suffer from the file and directory problems found in some applications you use (such as listing entries the user can’t access). In the following example, you create an application that prints separate lists of directories and files, along with a number of useful attributes for each entry.

Files needed: GetAttributes.java

1. Open the editor or IDE that you’ve chosen to use for this book.

2. Type the following code into the editor screen.

// Import the required API classes.
import java.io.File;
import java.util.Calendar;

public class GetAttributes
{
public static void main(String[] args)
{
// Create an object that holds the current 

// directory.
File Dir = new File(".");

// Obtain a list of child entries in the 

// directory.
String[] Children = Dir.list();

// Check each entry for a directory.
System.out.println("Directories:");
for (String Child : Children)
{
// Create a File object for the child.
File ChildDir = new File(Child);

// Determine whether the child is a file.
if (ChildDir.isDirectory())
{
// Display the attributes.
ShowAttributes(ChildDir);
}
}

// Check each entry for a filename.
System.out.println("\nFiles:");
for (String Child : Children)
{
// Create a File object for the child.
File ChildFile = new File(Child);

// Determine whether the child is a file.
if (ChildFile.isFile())
{
// Display the attributes.
ShowAttributes(ChildFile);
}
}
}

public static void ShowAttributes(File Entry)
{
// Display the filename.
System.out.println(Entry.getName());

// Display the attributes.
System.out.print("\tHidden? " + Entry.isHidden());
System.out.print("\tExecutable? " +
Entry.canExecute());
System.out.print("\tReadable? " + Entry.
canRead());
System.out.println("\tWriteable? " +
Entry.canWrite());

// Display the statistics.
Calendar FileDate = Calendar.getInstance();
FileDate.setTimeInMillis(Entry.lastModified());
System.out.format("\tLast Modified: %te %tB %tY",
FileDate, FileDate, FileDate);
System.out.println("\tSize: " + Entry.length());
}
}

The example begins in the main() method. As with previous examples in this chapter, the code begins by obtaining a list of entries in the current directory. It then processes each of the entries by looking first for directories and then for files, using the same technique as used in the ShowFiles example.

In this case, instead of printing the directory or filename, the code calls ShowAttributes() with the File object, ChildDir or ChildFile. The ShowAttributes() method begins by displaying the entry name (file or directory).

Displaying attributes, such as hidden, executable, readable, and writeable, requires only that you call the required method. When working with a production application, you’d use these attributes to determine what you can do with the entry. For example, before you write data to a file, you should ensure that the file supports writing.

Files and directories also have statistics associated with them, such as size and date of last modification. Java doesn’t support all of the statistics supported by all of the file systems for each of the platforms. Instead, it focuses on common statistics. In this case, the example shows how to print the date that the file or directory was last modified and the size of the directory or file.

The date you receive is the number of milliseconds since January 1st, 1970, which isn’t particularly useful. The example shows how to convert that value into a usable date by creating a Calendar object, FileDate, and then calling setTimeInMillis() with the date and time contained inEntry.lastModified(). The example then uses the same code shown in the DisplayDateTime example from Chapter 4 to display the date.


EXTRA INFO

The new date and time API provided with Java 8 (described in the “Using the New Date and Time API” section of Chapter 3) can shorten the code for obtaining a file date a little. Instead of the two-step process shown in the example, you can substitute a single line of code: Date FileDate = new Date(Entry.lastModified());. To make this bit of code work, you must also add import java.util.Date; to the beginning of the listing. However, the difference in executable size and application speed is negligible, and the technique shown works with older versions of Java.


3. Save the file to disk using the filename GetAttributes.java.

4. In your command prompt, type javac GetAttributes.java and press Enter.

The compiler compiles your application and creates a .class file from it.

5. Type java GetAttributes and press Enter.

The application displays the attributes for both files and directories contained in the current directory, as shown in Figure 12-3. Notice that the directory entries show 0 for the size statistic. That’s because directories are containers and don’t contain any data. Files generally contain data, so they have a size. (If you’re using the downloadable source rather than creating the files from scratch, your listing will contain the attributes for all of the files and directories for the chapter.)

9781118098783-fg1203.tif

Figure 12-3:

remember.eps Just because a file or directory has a certain attribute, it doesn’t mean that it makes sense to perform the associated task on the file or directory. For example, even if a directory returns true when you make the canExecute() method call, it doesn’t mean you can actually execute a directory. In fact, you can execute only files that contain the right kind of code. Likewise, even if an executable file has the writeable attribute set to true, it doesn’t mean that you should write anything to the file. Attributes specify what you can do, not what you should do.

Manipulating path data

A path describes a location. Absolute paths always begin at the root directory of a drive and work toward the directory or file in question. Relative paths describe the location of a file or directory in relation to the current directory. The current directory is always described using a single period (.), while the parent directory is described using two periods (..). The use of one or two periods to describe a location is a kind of relative path. In the following example, you discover the absolute and relative paths of directories and files.

Files needed: ShowPaths.java

1. Open the editor or IDE that you’ve chosen to use for this book.

2. Type the following code into the editor screen.

// Import the required API classes.
import java.io.File;

public class ShowPaths
{
public static void main(String[] args)
{
// Create an object that holds the current 

// directory.
File Dir = new File(".");

// Obtain a list of child entries in the 

// directory.
String[] Children = Dir.list();

// Check each entry for a filename.
for (String Child : Children)
{
// Create a File object for the child.
File ChildFile = new File(Child);

// Display the relative path.
System.out.println(ChildFile.getPath());

// Display the absolute path.
System.out.println(ChildFile.
getAbsolutePath());
}
}
}

In this example, the application begins by getting the list of directories and files in the current directory. It then processes each of these entries one at a time. The call to getPath() displays the relative path, which is simply the name of the directory or file in this case. On the other hand, the call to getAbsolutePath() provides a precise location for this file or directory on disk.

3. Save the file to disk using the filename ShowPaths.java.

4. In your command prompt, type javac ShowPaths.java and press Enter.

The compiler compiles your application and creates a .class file from it.

5. Type java ShowPaths and press Enter.

The application displays the path information for each of the files and directories in the current location. The precise information you see in Figure 12-4 will vary by your operating system. Each operating system provides a unique way to display path information. The output you see in Figure 12-4 is for the Windows operating system. (If you’re using the downloadable source rather than creating the files from scratch, your listing will contain the path information for all of the files and directories for the chapter.)

9781118098783-fg1204.tif

Figure 12-4:

Opening Files for Reading

Files aren’t very useful unless you can access the information they contain. For this example, you access the information in the MyText.txt file you created in the “Managing directory information” section of the chapter. However, file access largely works the same way no matter what sort of file you open. In the following example, you open a file, read its content, and display the content onscreen.

Files needed: ReadData.java

1. Open the editor or IDE that you’ve chosen to use for this book.

2. Type the following code into the editor screen.

// Import the required API classes.
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

public class ReadData
{
public static void main(String[] args)
{
// Create the file input stream.
FileInputStream Input = null;
try
{
Input = new FileInputStream("MyText.txt");
}
catch (FileNotFoundException e)
{
// Display an error message if the file is 

// missing.
System.out.println("The file doesn't
exist!\n" + e.getMessage());

// Exit without doing anything more.
return;
}

// Define an object to read from the stream.
Scanner Reader = new Scanner(Input);

// Read each line in turn and display it.
while (Reader.hasNextLine())
System.out.println(Reader.nextLine());

// Close the file when you're done.
try
{
Input.close();
}
catch (IOException e)
{
// Generate an error message when necessary.
System.out.println("Couldn't close the
file!/n" + e.getMessage());
}
}
}

Reading a file begins with the FileInputStream, Input. Think of the FileInputStream as a kind of conduit that transfers data from disk to your application. The FileInputStream requires you to provide the name of the file as a minimum. When the file is outside of the current directory, you must also provide the complete path to that file. Notice that you must enclose this code within a try…catch block, just in case the file doesn’t exist. If the file doesn’t exist, the application displays an informational message and exits because there isn’t anything to process.


LINGO

A data stream is a connection between an application and a data source of some type. Streams come in many different forms and work with a multitude of locations. This chapter helps you understand file streams, which are used to read data from and write data to the disk.


There are a number of ways to request information from the FileInputStream. This example shows the easiest method, using a Scanner object, Reader. You use precisely the same technique for reading from a text file as you do from the keyboard. However, the data file represents pre-recorded input, so the example calls hasNextLine() to determine whether there’s any more input to process. When there’s input to process, the code calls nextLine() to obtain the input as a string.

warning.eps Whenever you read or write from a file, you must always close the file when you’re done using it. There are many potential problems that occur when you fail to close the file. At a minimum, the application could cause a memory leak in the underlying operating system, which would make the memory inaccessible to other applications and could possibly cause system instability. In addition, failure to close the file could cause damage to the data the file contains. Because there are situations where closing the file might not work, such as the user deleting the file before it gets closed, you must also encase the Input.close() call in a try…catch block.

3. Save the file to disk using the filename ReadData.java.

4. In your command prompt, type javac ReadData.java and press Enter.

The compiler compiles your application and creates a .class file from it.

5. Type java ReadData and press Enter.

The application displays the content of the MyText.txt data file, as shown in Figure 12-5. The output from your example will vary from that shown in Figure 12-5 if you’ve modified the content of MyText.txt.

9781118098783-fg1205.tif

Figure 12-5:


EXTRA INFO

The Java 8 Files.list() method returns a Stream object that contains all of the lines of data found in the file you specify. One of the advantages of this method is that you can specify the character set (such as UTF-8) used when reading the file. You can use theBufferedReader.lines() method (found in the java.io.BufferedReader package) to improve the performance of reading larger files, but be aware that you do so at the expense of using additional memory resources to store the buffered data. The output is still aStream object. You can read more about the BufferedReader at http://download.java.net/jdk8/docs/api/java/io/BufferedReader.html.


Writing to Files

Writing to a file saves the data you write for later use. Data can take any form that you normally create with your computer. Of course, the MyText.txt file contains textual information. However, the same techniques used to write text data can apply to other sorts of data. The actual implementation can vary a little, but the idea is the same. In the following example, you create an application that can write data to a file.

Files needed: WriteData.java

1. Open the editor or IDE that you’ve chosen to use for this book.

2. Type the following code into the editor screen.

// Import the required API classes.
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.Scanner;
import java.lang.String;

public class WriteData
{
public static void main(String[] args)
{
// Create the file output stream.
FileOutputStream Output = null;
try
{
Output = new FileOutputStream("MyText.txt");
}
catch (FileNotFoundException e)
{
System.out.println("The file doesn't
exist!\n" + e.getMessage());
}

// Define an object to write to the stream.
OutputStreamWriter Writer =
new OutputStreamWriter(Output);

// Create a string for input data.
String Data = "";

// Define a means for inputting from the 

// keyboard.
Scanner GetData = new Scanner(System.in);

// Keep processing data until told otherwise.
while (Data.toUpperCase().compareTo("DONE") != 0)
{

// Get some input from the user.
System.out.print(
"Type something to write to the file or
DONE to exit: ");
Data = GetData.nextLine();

// Write each line in turn.
try
{
Writer.write(Data + "\n");
}
catch (IOException e)
{
// Display an error message.
System.out.println("Couldn't write to the
file!/n" +
e.getMessage());
}

// Display what was written.
System.out.println("Writing: " + Data);
}

// Close the file when you're done.
try
{
Writer.close();
}
catch (IOException e)
{
// Generate an error message when necessary.
System.out.println("Couldn't close the
file!/n" + e.getMessage());
}
}
}

Compare the code in this example with the ReadData example and you see that there are many similarities. What has changed is that instead of reading data, you’re outputting data. In sum, the direction of information flow has changed. With this in mind, the application creates aFileOutputStream, Output, and uses it to create an OutputStreamWriter, Writer.

In order to make this example a bit more realistic, the application creates a Scanner, GetData, and uses it to obtain input from the user. When the user types a new value and presses Enter, the application outputs it to the data file and also writes it onscreen. To end the application, the user types Done (in any case) and presses Enter.

As with reading data, you must close the file when the application ends. Otherwise, it’s almost certain that you’ll experience data loss. The same sorts of exceptions occur with this application as when you read data.

3. Save the file to disk using the filename WriteData.java.

4. In your command prompt, type javac WriteData.java and press Enter.

The compiler compiles your application and creates a .class file from it.

5. Type java WriteData and press Enter.

The application asks you to provide some input data to write to the file.

6. Type Hello and press Enter.

The application tells you that it has written the data to disk.

7. Type Done and press Enter.

The application ends. Of course, you don’t really know whether the application has worked — it could tell you anything! This is one situation where you can check the functionality of one example by using another example.

8. Type java ReadData and press Enter.

You see the strings that you previously typed as shown in Figure 12-6. Notice that the original string is overwritten with the new data.

9781118098783-fg1206.tif

Figure 12-6:

Creating and Using Temporary Files

As their name implies, temporary files are used to temporarily store information on disk. Applications use temporary files for a lot of different tasks — everything from making a backup of a data file before writing information to it to using the disk in place of memory as a scratchpad for information. In the following example, you create, write, and read a temporary file on disk.

Files needed: UseTempFiles.java

1. Open the editor or IDE that you’ve chosen to use for this book.

2. Type the following code into the editor screen.

// Import the required API classes.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.Scanner;
import java.lang.String;

public class UseTempFiles
{
public static void main(String[] args)
{
// Create a temporary file.
File Temp = null;
try
{
Temp = File.createTempFile("MyTemp", ".txt");
}
catch (IOException e)
{
// Generate an error message when necessary.
System.out.println("Couldn't create the
file!/n" +
e.getMessage());

// Exit the application.
return;
}

// Configure the file for automatic deletion

// when
the application ends.
Temp.deleteOnExit();

// Write data to the file.
WriteData(Temp);

// Pause to look at the file.
System.out.print(
"Check the temporary file and then press
Enter.");
Scanner GetEnter = new Scanner(System.in);
GetEnter.nextLine();

// Read data from the file.
ReadData(Temp);
}

// Write data to the temporary file.
public static void WriteData(File Temp)
{
// Create the file output stream.
FileOutputStream Output = null;
try
{
Output = new FileOutputStream(Temp);
}
catch (FileNotFoundException e)
{
System.out.println("The file doesn't
exist!\n" + e.getMessage());
}

// Define an object to write to the stream.
OutputStreamWriter Writer =
new OutputStreamWriter(Output);

// Write some data to the file.
try
{
Writer.write("This is a temporary file!");
}
catch (IOException e)
{
// Display an error message.
System.out.println("Couldn't write to the
file!/n" + e.getMessage());
}

// Display what was written.
System.out.println("Writing Data.");

// Close the file when you're done.
try
{
Writer.close();
}
catch (IOException e)
{
// Generate an error message when necessary.
System.out.println("Couldn't close the
file!/n" + e.getMessage());
}
}

// Read the data back from the temporary file.
public static void ReadData(File Temp)
{
// Create the file input stream.
FileInputStream Input = null;
try
{
Input = new FileInputStream(Temp);
}
catch (FileNotFoundException e)
{
// Display an error message if the file is 

// missing.
System.out.println("The file doesn't
exist!\n" + e.getMessage());

// Exit without doing anything more.
return;
}

// Define an object to read from the stream.
Scanner Reader = new Scanner(Input);

// Read each line in turn and display it.
while (Reader.hasNextLine())
System.out.println(Reader.nextLine());

// Close the file when you're done.
try
{
Input.close();
}
catch (IOException e)
{
// Generate an error message when necessary.
System.out.println("Couldn't close the
file!/n" + e.getMessage());
}
}
}

This looks like a lot of code, but you already know how most of it works because you’ve already seen it in action. The WriteData() and ReadData() methods work just like the ReadData and WriteData examples in this chapter. The only difference is that instead of using a String to define the name of the file, this version uses the File object, Temp, to define it.

The main() method begins by creating a temporary File, Temp. This file has a filename that begins with MyTemp and has a file extension of .txt. The filename also includes a random number to make it unique. Consequently, you can use the same call to create as many temporary files as needed for your application. The application could always experience an error, such as a lack of hard drive space to create the temporary file, so you must encase this call in a try…catch block.

An important part of using temporary files is making sure they actually are temporary. If you look at the location used to hold temporary files on your hard drive, it almost certainly contains a wealth of temporary files that didn’t get deleted by the application that created them. This is an extremely poor way to write application code. To tell Java that you want to delete this file automatically, the application calls deleteOnExit().

At this point, the File object is used like any other File object to read and write data. The difference is that this data is temporary.

3. Save the file to disk using the filename UseTempFiles.java.

4. In your command prompt, type javac UseTempFiles.java and press Enter.

The compiler compiles your application and creates a .class file from it.

5. Type java UseTempFiles and press Enter.

The application writes data to the temporary file and tells you to find the temporary file on your system. Of course, the question is whether this temporary file actually exists and where you can find it on disk. The temporary file is real and you’ll see it in action in the next step. The location depends on your operating system. When working with a Macintosh or Linux system, you’ll likely find the file in your /tmp directory. In most cases, you can find the folder by executing the echo $TMPDIR command. Windows users will typically find the temporary files in their C:\Users\UserName\AppData\Local\Temp directory, where UserName is the user’s name. You can also obtain this information by executing the echo %Temp% command. In my case, the temporary files are found in the C:\Users\John\AppData\Local\Temp directory.

6. Locate the temporary file on your drive system.

You see a file similar to the one shown in Figure 12-7. The filename will contain MyTemp at the beginning and use the .txt extension, just as expected. In this case, the filename is MyTemp8399517910498436675.txt. The numbers in the middle are arbitrary. When you open this file, you see the text that the application wrote to it.

9781118098783-fg1207.tif

Figure 12-7:

7. Press Enter at the command prompt you used to run your application.

The application displays the temporary information as shown in Figure 12-8.

9781118098783-fg1208.tif

Figure 12-8:

8. Look at the temporary directory again.

Notice that the application has automatically deleted the file and cleaned up after itself. This is how your application should always work with temporary files.

summingup_fmt.eps Summing Up

Here are the key points you learned about in this chapter:

· Files store data in specific locations on your hard drive.

· Directories act as containers to hold both directories and files.

· A path describes the precise location of a file or directory on disk.

· Attributes make it possible to determine specifics about a file or directory, such as whether you can read or write it.

· An absolute path begins at the root directory of the host drive and contains every subdirectory between it and the location of the desired directory or file.

· A relative path begins at the current location and describes how to access the desired directory or file from that point.

· The single period (.) represents the current directory, while the double period (..) represents the parent directory.

· Reading and writing files involves the use of streams that act as conduits between the hard drive and the user application.

· Whenever you finish reading from or writing to a data file, you must close it or the file could become damaged.

· Temporary files are useful for creating backups of files while you write to them or acting as a scratchpad for your application.

Try-it-yourself lab

For more practice with the features covered in this chapter, try the following exercise on your own.

1. Open the ReadData.java file supplied with the source code for this book.

2. Save the file as ReadData2.java.

3. Change the class name to ReadData2.

The class name must always match the filename. Otherwise, Java won’t compile the file for you.

4. Create a file named MyInt.txt and fill it with the numbers 1 through 5, separated by spaces.

The numbers should appear as 1 2 3 4 5. The space helps Java recognize individual integer values.

5. Change the Input line to use the new file by changing the FileInputStream constructor.

You change this text to read FileInputStream("MyInt.txt").

6. Change the Reader loop so it handles int values rather than strings.

Your code will look similar to this:

while (Reader.hasNextInt())
System.out.println(Reader.nextInt());

7. Compile and run the application.

Does the application output the correct results? How could you change this application to work with char values instead?

Know this tech talk

· attribute: An indicator of the configuration or status of a file or directory on disk. One attribute describes whether the entry is a file or a directory. Other attributes describe whether the entry is readable, writeable, or hidden. There are also statistics associated with the entries, such as the date of last modification and the size of a file.

· directory: A container used to store files or other directories on disk. Directories help organize the disk content and make it easier to find.

· file: A permanent storage container on disk for data. A file can contain both textual and binary data.

· path: A string that can start with a volume letter or name, a list of directory entries, and sometimes ending with a filename that describes the location of a directory or file on disk. Paths can take a number of forms. An absolute path always starts at the root directory of the disk and moves down through the directory hierarchy toward the directory or file in question. Relative paths describe the location of a file or directory in relation to the current location on disk.

· stream: A connection between an application and a data source used to transfer data to or from the application. Streams normally flow in one direction: either input or output. If you want to read data from a data source, you use an input stream. On the other hand, if you want to write data to a data source, you use an output stream.