Reading and Writing Local Files in Flash Player 10
One of the new features in Flash Player 10 are new ActionScript FileReference APIs that allow Flash content to directly read and write data to the user’s system.
Prior to Flash Player 10, in order to read or write a file to the user’s system, Flash content would first have to bounce it off of a server, and then load it back to the users system before it could be accessed. This was not only a hassle to program, but added additional application latency and resource usage.
The new functionality is achieved through the addition of two new APIs on the FileReference class:
FileReference.load() : Loads data from a file selected by the user.
FileReference.save() : Saves data to a file location selected by the user.
A couple of points to keep in mind:
- The load() and save() APIs can only be called in response to user interaction (such as a button click).
- The locations of the loaded and save files are not exposed to ActionScript.
- The APIs are asynchronous (non-blocking).
Below are two examples that show how to use the APIs. The examples use Flex for the UI, but the ActionScript is the same regardless of whether you are using Flex or not. The examples are fully commented.
Read a file from the users system:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.events.IOErrorEvent;
import flash.events.Event;
import flash.utils.ByteArray;
//FileReference Class well will use to load data
private var fr:FileReference;
//File types which we want the user to open
private static const FILE_TYPES:Array = [new FileFilter("Text File", "*.txt;*.text")];
//called when the user clicks the load file button
private function onLoadFileClick():void
{
//create the FileReference instance
fr = new FileReference();
//listen for when they select a file
fr.addEventListener(Event.SELECT, onFileSelect);
//listen for when then cancel out of the browse dialog
fr.addEventListener(Event.CANCEL,onCancel);
//open a native browse dialog that filters for text files
fr.browse(FILE_TYPES);
}
/************ Browse Event Handlers **************/
//called when the user selects a file from the browse dialog
private function onFileSelect(e:Event):void
{
//listen for when the file has loaded
fr.addEventListener(Event.COMPLETE, onLoadComplete);
//listen for any errors reading the file
fr.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
//load the content of the file
fr.load();
}
//called when the user cancels out of the browser dialog
private function onCancel(e:Event):void
{
trace("File Browse Canceled");
fr = null;
}
/************ Select Event Handlers **************/
//called when the file has completed loading
private function onLoadComplete(e:Event):void
{
//get the data from the file as a ByteArray
var data:ByteArray = fr.data;
//read the bytes of the file as a string and put it in the
//textarea
outputField.text = data.readUTFBytes(data.bytesAvailable);
//clean up the FileReference instance
fr = null;
}
//called if an error occurs while loading the file contents
private function onLoadError(e:IOErrorEvent):void
{
trace("Error loading file : " + e.text);
}
]]>
</mx:Script>
<mx:Button label="Load Text File" right="10" bottom="10" click="onLoadFileClick()"/>
<mx:TextArea right="10" left="10" top="10" bottom="40" id="outputField"/>
</mx:Application>
Write a file to the users system:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import flash.net.FileReference;
import flash.events.IOErrorEvent;
import flash.events.Event;
private static const DEFAULT_FILE_NAME:String = "example.txt";
//FileReference Class well will use to save data
private var fr:FileReference;
/********** UI Event Handlers **************/
//called when the users types in the textarea
//note valueCommit should be used, but is broken in the flex build
//I am using
private function onInputChange():void
{
//enable button if there is any text to save
saveButton.enabled = (inputField.text.length > );
}
//called when the user clicks the load file button
private function onSaveClick():void
{
//create the FileReference instance
fr = new FileReference();
//listen for the file has been saved
fr.addEventListener(Event.COMPLETE, onFileSave);
//listen for when then cancel out of the save dialog
fr.addEventListener(Event.CANCEL,onCancel);
//listen for any errors that occur while writing the file
fr.addEventListener(IOErrorEvent.IO_ERROR, onSaveError);
//open a native save file dialog, using the default file name
fr.save(inputField.text, DEFAULT_FILE_NAME);
}
/***** File Save Event Handlers ******/
//called once the file has been saved
private function onFileSave(e:Event):void
{
trace("File Saved");
fr = null;
}
//called if the user cancels out of the file save dialog
private function onCancel(e:Event):void
{
trace("File save select canceled.");
fr = null;
}
//called if an error occurs while saving the file
private function onSaveError(e:IOErrorEvent):void
{
trace("Error Saving File : " + e.text);
fr = null;
}
]]>
</mx:Script>
<mx:Button label="Save File" right="10" bottom="10" id="saveButton"
click="onSaveClick()" enabled="false"/>
<mx:TextArea right="10" left="10" top="36" bottom="40" id="inputField"
editable="true" change="onInputChange()"/>
<mx:Label text="Enter text to save" left="10" top="10" fontWeight="bold"/>
</mx:Application>
In addition to the events shown in the examples above, the following events are also broadcast by the APIS:
- ProgressEvent.PROGRESS : Gives progress on the reading or writing of the file
- Event.OPEN : Broadcast when the file is opened for reading or writing.
While it will also be possible to use these APIs in Adobe AIR, in general, you will want to use the AIR File APIs as they provide more functionality and flexibility.
You can download the Flash Player 10 ActionScript APIs docs from here.
You can find more information on Flash Player 10 on labs.