Accessibility
Jeff Swartz

Jeff Swartz

Adobe

Created:
25 February 2008
User Level:
Intermediate, Advanced
Products:
Adobe AIR

Building a directory search application

The directory search sample application, shown in Figure 1, demonstrates the following features of working with files in Adobe AIR:

  • Reading files asynchronously so that other ActionScript processes can take place as file data is read
  • Getting the file name extension from file names
  • Using the platform-specific nativePath property of a File object

File Search application

Figure 1. This sample application enables you to search for specific files.

Note: This is a sample application provided, as is, for instructional purposes.

Requirements

To make the most of this article, you need the following software and files:

Adobe AIR

Adobe Flex Builder or Flex SDK (version 3 or later)

Sample files:

This sample application includes the following files:

  • FileSearch.mxml: The main application file in MXML for Flex; includes the code discussed in this article
  • FileSearch-app.xml: The AIR application descriptor file
  • Sample AIR icon files

Important

The application descriptor file, FileSearch-app.xml, uses the AIR 1.0 namespace. If you are compiling the application using Flex Builder 3.0.2 or Flex SDK 3.2 or later, edit the file to use the AIR 1.5 namespace:

xmlns="http://ns.adobe.com/air/application/1.5"

Otherwise, you will not be able to test or package the application.

Prerequisite knowledge

General experience of building applications with Flex Builder or the Flex SDK is suggested. For more details on getting started with this Quick Start, refer to Building the Quick Start sample applications with Flex.

Understanding the code

Note: This article does not describe all of the Flex components used in the MXML code for the file. For more information, see the Flex 3 Language Reference.

Setting the root directory to search

The init() method sets the text value of the folderPath TextInput component to a pre-defined path (the user's documents directory):

folderPath.text=File.documentsDirectory.nativePath;

File.documentsDirectory is a File object pointing to the user's documents directory (such as My Documents on Windows), and the nativePath property is a string value of the platform-specific path to the directory. For example, on Windows, this path could be:

C:\Documents and Settings\userName\My Documents

Whereas on Mac OS X, it could be:

/Users/userName/Documents

The user can edit this value (in the TextArea component), and when the user clicks the Search button, the search() method checks to see if the path is valid, and displays an error message if it is not:

var dir:File = new File(folderPath.text);
if (!dir.isDirectory)
{
    Alert.show("Invalid directory path.", "Error");
}

Notice the difference between the nativePath property and the url property of a File, listed here for the same directory File object:

trace(directory.nativePath); // C:\Documents and Settings\swartz\My Documents
trace(directory.url); // file:///C:/Documents%20and%20Settings/swartz/My%20Documents

Searching the directory for matching files

The main search process lists directory contents asynchronously, one at a time. By doing this, other ActionScript-based processes (such as the progress bar animation and result listing) can take place as Apollo gets directory listing information (asynchronously) from the file system.

The search() method sets up event listeners for the dirListing event, which is dispatched when the getDirectoryListingAsync() process has completed:

dir.addEventListener(FileListEvent.DIRECTORY_LISTING, dirListed);
dir.getDirectoryListingAsync();

The dirListed() method processes the list of files in the current directory. This list is represented as the files property of the dirListing event. The method sets a currentNodes variable to this array:

currentNodes = event.files;

The dirListed() method iterates through each member of this array, to see if it is a directory. If it is a directory, the object is added to a list of current subdirectories (of the current directory being examined).

node = currentNodes[i];
if (node.isDirectory)
{
    currentSubdirectories.push(currentNodes[i]);
}

After the iteration is completed, the members of this array are added to a master array of directories to be searched, named directoryStack :

for (i = currentSubdirectories.length - 1; i > -1; i--)
{
    directoryStack.push(currentSubdirectories[i]);
}

At this point, now that processing of the current directory is complete, the application can call another asynchronous listing of the next directory in the stack (if there is one):

var dir:File = directoryStack.pop();
if (dir == null) {
    progress.visible = false;
    // There are no further directories to search. The search is completed.
} else {
    dir.addEventListener(FileListEvent.DIRECTORY_LISTING, dirListed);
    dir.listDirectoryAsync();
}

Displaying search results

As the dirListed() method iterates through each member of this array of contents of the current directory, it checks if the name matches the Search pattern, and if so, it creates an object that is added to the ArrayCollection that is a data provider for the resultsGrid DataGrid component:

if (node.name.search(pattern) > -1)
{
    var newData:Object = {name:node.name,
    path:node.nativePath,
    type:node.extension};
    resultData.addItem(newData);
}

About the author

Jeff Swartz first worked at Macromedia (now Adobe Systems) in 1992. He is currently a technical writer for Adobe AIR. Jeff received a bachelor's degree in Computer Science and Mathematics from the University of Illinois at Urbana-Champaign and studied at the Edinburgh University Department of Artificial Intelligence. Audiences around the San Francisco Bay Area have tolerated Jeff's artistry on the trombone. He has served as Big Frank, a dancing hot dog, for Vienna Beef Ltd.