dcsimg

The Adobe AIR File API

Typical browser applications cannot access the local filesystem. However, Adobe AIR applications can, giving those applications a distinct advantage. Learn how the AIR File API works and build an application that can read and write from a local disk. Someday, your browser will do the very same thing.

The method names are generally self-explanatory, but as you can see from the method signatures, some allow you to filter the file types that the user can select. For example, you could do the following to browse for a file:

import flash.filesystem.*;
import flash.events.Event;
import flash.net.FileFilter;
var selectedFile:File = new File();
var fileFilter:FileFilter = new FileFilter("Text", "*.as;*.css;*.html;*.txt;*.xml");
try{
   selectedFile.browseForOpen("Open", [fileFilter]);
   selectedFile.addEventListener(Event.SELECT, fileSelected);
}  catch (error:Error)  {
   trace("Failed:", error.message);
}
function onFileSelected(evt:Event):void   {
  var stream:FileStream = new FileStream();
  stream.open(evt.target, FileMode.READ);
  var fileData:String = stream.readUTFBytes(stream.bytesAvailable);
  trace(fileData);
}

This example traces the output of the selected file and uses the FileFilter class and the FileStream class.

Other Useful File Methods

Before moving on to the sample application, let me point out some other things that you can do with the File class. The File API has the following methods that allow you to perform actions common to desktop applications:

  • copyTo(newLocation:FileReference, overwrite:Boolean = false):void: Copies the file or directory at the location specified by this File object to the location specified by the newLocation parameter
  • copyToAsync(newLocation:FileReference, overwrite:Boolean = false):void: Begins copying the file or directory at the location specified by this File object to the location specified by the destination parameter
  • createDirectory():void: Creates the specified directory and any necessary parent directories
  • deleteDirectory(deleteDirectoryContents:Boolean = false):void: Deletes the directory
  • deleteDirectoryAsync(deleteDirectoryContents:Boolean = false):void: Deletes the directory asynchronously
  • deleteFile():void: Deletes the file
  • deleteFileAsync():void: Deletes the file asynchronously
  • moveTo(newLocation:FileReference, overwrite:Boolean = false):void: Moves the file or directory at the location specified by this File object to the location specified by the destination parameter
  • moveToAsync(newLocation:FileReference, overwrite:Boolean = false):void: Begins moving the file or directory at the location specified by this File object to the location specified by the newLocation parameter
  • moveToTrash():void: Moves a file or directory to the trash
  • moveToTrashAsync():void: Asynchronously moves a file or directory to the trash

As you can see, the File API allows you to do just about anything you can think of with a file.

Also note that there are a number asynchronous versions of certain methods.With the synchronous versions of the methods, the code waits for the method to return before moving on to the next line of your code:

var someFile:File = File.userDirectory.resolve( "someTextFile.txt" );
 someFile.copyTo( File.desktopDirectory.resolve( "Copy of someTextFile.txt" ) );
  trace( "Done Copying" );
// Trace displays after "copyTo" is complete

In the asynchronous versions of the methods, the operation is started in the background while code execution continues. An event named complete is generated by the background process when the operation is complete:

import flash.filesystem.File;
import flash.events.Event;
var someFile:File = File.documentsDirectory;
someFile = someFile.resolvePath("someTextFile.txt");
var destination:File = File.documentsDirectory;
destination = destination.resolvePath("copyOfSomeTextFile.txt");
someFile.copyToAsync(destination, true);
sourceFile.addEventListener(Event.COMPLETE, fileCopiedHandler);
function fileCopiedHandler(event:Event):void {
  trace("Done.");
}

This brief overview should be enough to give you a sense of what the File API and—more specifically—the File class will allow you to do in your AIR applications. Now, let’s take a look some of the pre-built components that come with Flex and make working with the File API easier.

Flex File System Controls

Flex comes with a number of components that make browsing the local file system an easy task:

  • FileSystemComboBox control: A combo box control for selecting a location in a file system
  • FileSystemTree control: Displays the contents of a file system directory as a tree
  • FileSystemList control: Displays the contents of a file system directory as selectable items in a scrolling list
  • FileSystemDataGrid control: Displays file information in a data grid format
  • FileSystemHistoryButton control: Allows the user to move backwards or forwards through the navigation history of another control (works in conjunction with a FileSystemList or FileSystemDataGrid control or any similar control with a property containing an array of File objects)

Of these, the first four are simply different methods of displaying file information. The FileSystemHistoryButton control, however, is a navigational aid that works in combination with one of the other controls. You will see where the FileSystemHistoryButton control can be useful when you build the sample application.

The use of the display controls is simply a matter of telling it what directory to start in using a File object and telling it what files to display using a filter. You’ll be using the FileSystemList control in the sample application, so let’s move on to that now.

Sample Application: An Image Browser

The following example shows how to use a FileSystemList to set the source attribute of an image object using the selected item in the FileSystemList.

First, create an AIR project in Flex Builder. Creating an AIR application is just like creating any other Flex application, except that you select Desktop Application during the project-creation process:

The Select AIR Project
The Select AIR Project

If you open the main application file, you will see:

<?xml version="1.0" encoding="utf-8"?>
   <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

 </mx:WindowedApplication>

The only difference here between an AIR application and a standard Flex application is that the main tag is named <WindowedApplication> rather than <Application>.

Edit the code so that it looks like the following:

<?xml version="1.0" encoding="utf-8"?>
   <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
   <mx:Script>
 <![CDATA[
 import mx.events.ListEvent;
 import flash.filesystem.File;
 [Bindable]
 private var allowedFiles:Array = ['.jpg', '.png']
 private function displaySelectImage(event:ListEvent):void{
   var selectedFile:File = event.target.selectedItem as File
   if (!selectedFile.isDirectory){
     this.imageDisplay.source = selectedFile.nativePath;
   }
 }
 ]]>
 </mx:Script>
 <mx:HBox>
 <mx:FileSystemList x="10" y="10" id="fileList" directory="{File.userDirectory}" extensions="{this.allowedFiles}"  itemClick="displaySelectImage(event)"/>
 <mx:Image id="imageDisplay" x="180" y="10" height="204" width="320"/>
 </mx:HBox>
 </mx:WindowedApplication>

As you can see, there isn’t a lot to this application. The allowedFiles property simply acts as filter that tells the FileSystemList what types of files to display. In this case, you’re only interested in image files that Flex can display, so I have limited it to JPG and PNG files. This filter is applied by extensions="{this.allowedFiles}" in the <FileSystemList> tag. As for the rest of the <FileSystemList> tag, take note of directory="{File.userDirectory}": This sets the initial directory using one of the static attributes from the File class. The itemClick="displaySelectImage(event)" is simply an event handler to trigger a function when the user selects an item from the list. The function it triggers is:

private function displaySelectImage(event:ListEvent):void{
   var selectedFile:File = event.target.selectedItem as File
   if (!selectedFile.isDirectory){
     this.imageDisplay.source = selectedFile.nativePath;
    }
   }
   

Note that the event type is ListEvent, because itemClick is an event that is inherited from the List component. In a FileSystemList, the selected item is a File object, so you simply create a variable cast to that type. You only want to set the source of the image if the selectedItem is a file, not a directory, so you use the isDirectory property of the File object to determine this. Because you are already filtering for image types, you don’t have to worry about that detail. If the file is an image object, the source attribute of the image object is updated, and viola! the image is displayed:

The finished application
The finished application

Although this application is by no means meant to be release worthy, if you compiled it, you may notice something about the FileSystemList—namely, once you navigate to a folder, there is no way to return to the parent folder. This is where the FileSystemHistoryButton control can be useful. You could use one of the other controls, but I’ll let you play with that on your own.

Summary

With AIR moving applications from the Web browser to the desktop, all sorts of new possibilities arise. File system access via the File API is definitely one of the capabilities that bring these new possibilities into existence. As with any new programming feature, the best way to get familiar with it is to play with it. Although certainly not exhaustive, this article provides enough detail to get you started.

Fatal error: Call to undefined function aa_author_bios() in /opt/apache/dms/b2b/linux-mag.com/site/www/htdocs/wp-content/themes/linuxmag/single.php on line 62