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 andmore specificallythe 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
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
Although this application is by no means meant to be release worthy, if you compiled it, you may notice something about the FileSystemListnamely, 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.
Jeremy Wischusen has over 12 years experience designing websites and applications such clients as myYearbook.com, HBO and others. In the past, he taught web design for clients such as Wyeth Pharmaceuticals and The Vanguard Group and is currently an instructor at the University of the Arts department of continuing education in Philadelphia teaching web design and ActionScript. Jeremy is also an active member of the Flashkit online flash community where he has composed several tutorial on Object Oriented ActionScript. Currently Jeremy works for GoAmerica as a Flex/Flash PHP Developer.
Comments on "The Adobe AIR File API"
I’m not so sure that web apps accessing my local filesystem are a good thing. Sounds like a security hole just waiting to be exploited.
I’m so sure that web apps accessing my local filesystem ara a bad thing ™. Is a security hole waiting to be exploited.
You need to be a part of a contest for one
of the finest websites on the internet. I am going to highly recommend this
website!