File, Meet Directory


The java.io package has a File class, which creates a system-independent cover for file paths and names. A "file" for this purpose may be either a disk file or a (sub)directory. I wanted a proper Directory class that would encapsulate directory knowlege - the files and subdirectories that are part of this directory.

This proved easy to write and immensely useful.

The Directory Extends File

What should a directory have that java.io.File doesn't have? I decided that a list of subdirectories and a separate list of files would meet my needs. I used my TypeArray to create a DirectoryArray and a FileArray. These are object wrappers for self-expanding, strongly-typed arrays, in this case Directory[] and File[].

It wasn't until I wrote the constructor that I realized just how lucky I'd been! Start with a path to build a Directory. From that path, create a File. Use the listfiles() method to get an array of references to the File objects that are included in this directory. Then loop through them placing directories in the DirectoryArray and the others into the FileArray.

Accidental Recursion

I could probably get away with bragging about the brilliance of the design, but it would be a lie. I was muddling along, building straightforward code when I realized that I'd need to use the Files that were directories (isDirectory() reports true) to create Directory references or my Directory array, being strongly typed, wouldn't accept them. No problem, just take the file, get the path and create a new Directory.

This is the constructor:


	public Directory( String pathname ) {

	    super(pathname); 

        File[] fs = listFiles();

        for ( int i = 0; i < fs.length; i++ ) {
            if ( fs[i].isDirectory() ) {
                dirs.add( new Directory
                    (fs[i].getPath( )) );
            }
            else files.add( fs[i] );
        }

	} // end of Directory()
That's the entire class logic, not counting some getters and a toString() method. It wasn't until after I wrote it that I looked at it and realized that I had just created an arbitrarily deep tree structure. For each subdirectory this constructor calls itself to create another "dirs" (DirectoryArray) and "files" (FileArray). In turn, that will create a "dirs" for each subdirectory listing the sub-subdirectories, and so on.

Summary

I wrote this to create a Javadoc-like tree - root directory, packages, then source code wrapped into .HTML files. I didn't know when I wrote it that I'd just solved all the tree-climbing issues, but I had. Just create a Directory for the root and the whole tree is built, ready to use. For each directory, handle the "files" list creating the HTML, and then march through the "dirs" list recursively.

Next time you need to climb around a directory tree, just drop in a Directory. Creating a Directory (Directory dir = new Directory("/Some/Root");) builds the entire file/directory tree from the given root on down.

This code is free for non-commercial use. Download the Directory, DirectoryArray and FileArray classes from the programmer.javasrc package. You can get them from the javasrc here.

© 2005 by Martin Rinehart


java consultant home page icon

Back to Articles