Get your apps moving with Java streams

Managing the files in your application doesn't have to be confusing. This article will show you how to work with Java streams and File objects.

The package contains classes for managing both files and streams of data. A Java stream is a chunk of sequential data you can manage to suit the needs of your application.

Files are stored as sequential sets of bytes on a storage device. You can read from a file using an input stream and store the bytes in a temporary byte array, or write to a new file using an output stream. Using streams, you can perform automated tasks such as backing up a set of directories on your server, reading characters from a text file, and writing a text message to a log file.

The key components of the package are the File object, InputStreams and OutputStreams, FileStreams, Readers, and Writers.

File objects
Before we get started with the business of turning those files into streams, you need a good understanding of the File object. The File object represents a file or folder on the local file system. Note that declaring a File object does not create a file on the file system.

Exception handling is important when you're dealing with the file system. Files may not exist—or it may not be possible to create a folder with the path you specify.

The following examples show the use of the File object’s methods.

Making a new directory
Use the following code to create new directories. Make an object to represent the new directory, and then call the mkdir() method to create the directory:
//Create File Object
File newDir = new File(“d:/test/mydocs/”);
//Create New Directory

Deleting a file
Deleting a file is easy. Just create the File object for the intended file and call the file’s delete() method, as shown in this snippet:
//Create File Object
File f = new File(“d:/test.txt”);
//Delete the file


Listing a directory
Remember that the File object represents either files or folders. So if you want to get a listing of all the files in a directory, instantiate a File object as follows:
//Create File Object
File dir = new File(“d:/test/”);

Once you have the appropriate path, you can iterate through its contents:
//List directory
       String s[] = dir.list();
       for (int i=0; i<s.length; i++)
             //Iterate through files

The File object’s list() method returns a String array, which lists the contents of the directory—both files and folders.

This String array is often useful for displaying a directory’s contents to the user or for creating further file objects to search recursively through all of the directory’s folders and subfolders.

Input and output streams
Stream and Filter objects often confuse programmers. Figure A outlines the abstract model for handling streams and filters.

Figure A
Abstract input and output processes

The input process works like this:
  • ·        An input stream reads bytes from an input device.
  • ·        An input filter reads bytes from an input stream and returns data to its caller.

The output process works in a similar manner:
  • ·        An output filter receives data and writes bytes to an output stream.
  • ·        An output stream receives bytes and writes bytes to an output device.

This simple model is flexible because you can chain additional filters, extending the process to achieve a particular purpose.

File streams and filters
Let’s look at an example of the model described above. Our aim in this example is to read a file from the file system, buffer the streams, and then write the file to the file system using a different name. In effect, we are copying the file from one location to another (see Figure B). The code in Listing A provides one way to accomplish this.

Figure B
File input and output processes

Note the relationships between the abstract and file models:
  • ·        FileInputStream is a subclass of InputStream.
  • ·        BufferedInputStream is a subclass of FilterInputStream.

  • ·        BufferedOutputStream is a subclass of FilterOutputStream.
  • ·        FileOutputStream is a subclass of OutputStream.

Copying a directory
Listing B uses the copyFile method we used in Listing A, and with the file's list() method for directories, copies all the files (not folders) from one directory into another.

The method takes two String parameters—the name of the folder to be copied from and the name of the folder we are going to copy the files to.

Reader and Writer superclasses
Reader and Writer are the superclasses for all character streams. Both deal with Unicode characters, correctly handling conversions between local encodings and Unicode text.

Unicode is a standard for representing text and includes support for character sets such as the Indian, Korean, and Chinese sets. Java and XML use Unicode to represent the wide array of human languages.

Readers and Writers are always used when the source that is being read is textual, rather than InputStreams and OutputStreams, which deal with bytes.

Reading text from a file
FileReader is a subclass of InputStreamReader and is used for reading text from a file. BufferedReader, a subclass of Reader, improves the efficiency of character input operations.

Listing C includes an example that uses a FileReader and a BufferedReader to read text from a file.

Writing text to a file
FileWriter is a subclass of OutputStreamWriter and is used for writing text to a file. BufferedWriter, a subclass of Writer, improves the efficiency of character output operations.

Listing D uses a FileWriter to write a Java String to a file.

This tutorial started with an explanation of the File object and used it as a foundation for understanding Input and Output streams, as well as Readers and Writers.

You should have a better handle on how to create and delete files, copy files from one location to another, and read and write text files, all with the help of Java’s stream objects.





Editor's Picks