File searches are traditionally accomplished by an operating system utility. Most operating systems provide some sort of search facility that allows the user to track down misplaced or forgotten files. However, the facilities differ in their approach for searching files graphical versus command-line interface, comprehensive versus limited search capability.
If you work in multiple environments as I do, you become reliant on search functionality available in one environment that may not be supported in another. This article details a Java file search utility that provides a consistent user interface and consistent functionality when searching for files.
The FindFile utility is made up of two classes: FindFile and FindFileFrame, located in FindFile.java. The FindFile class (see Listing 1 on JDJ Web site) simply contains a main() method, which is the entry point for the application. The main() method instantiates the FindFileFrame class (see Listing 2 on Web site) where the utility's GUI is constructed and where the main processing logic is contained. The GUI is constructed using panels combined with three layout managers (java.awt.FlowLayout, java.awt.-
GridLayout and java.awt.BorderLayout) in favor of the more flexible, yet arguably more complicated and tedious java.-
awt.GridBagLayout layout manager. I work predominantly on Win32 operating systems (iWin9x, WinNT); therefore I modeled the FindFile utility's user interface (see Figure 1) after the Win32 Find utility (see Figure 2).
The FindFileFrame class implements the java.lang.Runnable interface and two event listener interfaces: java.awt.event.TextListener and java.awt.event.ActionListener. The java.awt.event.TextListener interface method, textValueChanged(), enables and disables the Find button based on the length of text entered in the File Name field. This prevents the user from starting a file search without first typing in something for a filename. The Look In field is optional and directs the utility to start the file search in the specified directory. If the field is left blank, the search is started in the current directory. The search is limited to the specified directory unless the Include Subfolders checkbox is selected. The user is able to specify a case-sensitive search by selecting the Case Sensitive checkbox.
The file search is performed in a separate thread via the java.lang.Runnable interface's run() method to allow the user the ability to interact with the utility. The run() method calls the updateUI() method with a true parameter to disable several user interface components prior to the search. The run() method then calls the checkForFile() method, which recursively cycles through any directories in the list only if the Include Subfolders checkbox is selected. The utility supports wild card character (i.e., * and ?) file searches through the use of a Java regular expression shareware package called pat, written by Steven R. Brandt and available at www.javaregex.com. Because the package uses a wild card character syntax slightly different from the format used for Win32 and UNIX operating systems, the entered filename is first converted to a format the package understands via the convert() method. If a file matching the specified filename is found, it's added to a java.awt.List component along with the file's fully qualified path. As the search progresses, the names of the directories searched are displayed in a java.awt.Label component located just below the search results. When the search is completed, the updateUI() method is called again, this time with a false parameter to enable the UI components.
A started thread normally stops when its run() method executes to completion. In the case of this utility, however, a Stop button is provided to allow the user to cancel the file search at any time. Prior to JDK 1.2.x, a thread was prematurely terminated by calling the java.lang.Thread class's stop() method. However, because of its unsafe behavior that method has since been deprecated (see the JDK 1.2.x javadoc HTML help file for the java.lang.Thread class's stop() method to view detailed information concerning the method's deprecation). Rather than use a deprecated, unsafe method I chose an alternative mechanism to terminate the file search prematurely. When the utility's Stop button is clicked, the boolean instance variable, searching, is set to false, causing the file search to end normally as this variable is interrogated in the checkForFile() method's for loop.
Typically, what is gained in portability with a Java program is usually lost in performance. However, with the advent of the HotSpot compiler this is becoming less of an issue. I compiled and tested the FindFile utility using the three major JDK releases (JDK 1.1.8, 1.2.2, and 1.3.0 RC2) on a 450 MHz Pentium III workstation with 96 MB of RAM running WinNT. The timings represent the average number of seconds both utilities took to search for the same file five times in succession. The results are listed in Figure 3. Your timings will vary based on the JVM and operating system in use, the operating system activity and the speed of your workstation's processor.
The FindFile utility detailed here provides a consistent user interface and consistent functionality when used in heterogeneous environments. The utility is quite functional as it stands; however, more features can easily be added if desired.
Pat Paternostro is an associate partner with the Tri-Com Consulting Group in Rocky Hill, Connecticut. Tri-Com provides
programming services for a wide variety of
Download Assoicated Source Files (Zip format - 11.5 KB)