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 > 0);
}
//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.






What’s the thinking behind the limitation to .load() and .save() in that they can only be called in ‘response to user interaction’?
Alex MacCaw
20 Aug 08 at 11:04 am
@Alex MacCaw
So you dont visit a website, and Flash content starts randomly reading and writing your files without your knowledge or permission.
mike chambers
mesh@adobe.com
mikechambers
20 Aug 08 at 11:40 am
Mike,
But surely a dialog would pop up for the user to select a file – they could just click cancel. Also I could potentially make a SWF that looked exactly like a textbox, for example, that would trick the user into clicking it. I’m not sure the limitation solves the problem.
Alex MacCaw
20 Aug 08 at 11:44 am
Unfortunately, this will break a ton of sites out there. You cannot call File.Browse() through ExternalInterface anymore. We rely on that at AOL for our photo uploader and I know that Flickr, Picnik and many other sites do this.
The ability to tie javascript and Flash so tightly together (as pushed in Flash 9 and AIR) is a huge reason that I use Flash in almost all my projects. I typically do UI in HTML and javascript, but use Flash underneath for uploading, media playback, byte manipulation, etc.
If Flash 10 releases like this, it will instantly break a ton of very popular sites (AOL, Yahoo) as well as make a lot of developers re-think about using Flash, as we now have to expose it in the UI which is not always possible. Please reconsider this security feature.
Dan kantor
20 Aug 08 at 1:09 pm
@Dan Kantor
–
Unfortunately, this will break a ton of sites out there.
–
This API is new to Flash Player 10, so it wont break anything (as nothing is using it yet).
I think what you are referring to are changes to security policy that affect existing FileReference APIs. You can find more information on that, as well as leave comments on this post:
http://theflashblog.com/?p=423
mike chambers
mesh@adobe.com
mikechambers
20 Aug 08 at 1:18 pm
Alex –
I also think one of the issues mentioned elsewhere was that without the user interaction, the origin of the Browse window is unknown. If you had 3 SWFs on a page (think mySpace or Facebook) , and a browse window popped up, the user wouldn’t know which one spawned it and may inadvertently compromise their system.
john
21 Aug 08 at 3:58 pm
John,
Just to be Devil’s Advocate for a second, I could create a transparent swf and overlay it over another – tricking a user into compromising their system. Another argument proposed is that an attacker could repeatedly open up the file browser, eventually forcing a user into selecting a file – I guess there’s some truth to this – but is there any examples of attackers actually using this technique? I know there’s always a compromise between security and convenience – but surely this is going too far? The Flash team strive really hard to make Flash backwards compatible, but aren’t they shooting themselves in the foot here? Sorry for the rant – but I’m really not convinced this measure is justified.
Alex MacCaw
22 Aug 08 at 3:36 am
[...] can read more about this on Mike Chambers blog, there are also sample applications to [...]
Reading and Writing Local Files in Flash Player 10 « Kun Janos around Adobe’s <Flex> and <Flash>
22 Oct 08 at 6:27 am
Hi Mike,
Great work, but how about selecting an mp3 file and playing that back?
I managed to load a text file, and an image, code like loadedImage.source = imageFR.data;, where loadedImage si mx:Image and imageFR is FileReference is working, but how to pass the content of a loaded mp3 file to the Sound component?
Also, I would like to select a video file and play that back without uploading to a server and downloading from there.
Kun Janos
29 Oct 08 at 1:08 am
This seems like a hackers dream come true.
Dude
2 Nov 08 at 11:15 pm
I for one am very pleased about this future, yes its a potential security hole if not looked after correctly but then you could quite easily say that about any other web development platform api, javascript, applets, activeX, silverlight and many others are far more evil than flash even ‘with’ these new features.
Thanks to adobe, I can now develop web apps that do what the client has asked for without sending it all back to the server first. Case in point saving images of a chart plus CSV data to local disk. And I have needed this functionality in the last three apps I wrote so I’m quite happy with it and will be ingorning the scaremongers.
L :0
SpookuLuke
4 Nov 08 at 8:14 am
When loading the ByteArray from the data property of a FileReference object, is there any way to buffer the bytes so they don’t all get read into memory?
We would like to use the fact that we have access to the ByteArray to be able to perform a resumable upload using Flash by sending the file one chunk at a time, however, for large files this becomes a problem if the whole file gets read into memory.
Are there any workarounds?
Jesse
6 Nov 08 at 6:46 am
I tried this as is in Flex Builder 3 .. and it doesnt work.. it doesnt even compile because it references to some API that dont exist.
Marc
12 Nov 08 at 7:12 pm
–
I tried this as is in Flex Builder 3 .. and it doesnt work.. it doesnt even compile because it references to some API that dont exist.
–
Have you setup Flex Builder 3 to compile to Flash Player 10?
mike chambers
mesh@adobe.com
mikechambers
13 Nov 08 at 12:16 am
Sometimes it’s not so much security as it is lazy programming. URLRequest can be used to load a file locally.
Knight Chat X
13 Nov 08 at 1:27 am
Use string and data manipulation functions to read the data as you would old school it works just fine assuming you know how to use the basic editing functions.
Knight Chat X
13 Nov 08 at 1:39 am
i installed the 3.2.0.3794 SDK .. and it still doesnt work
Marc
13 Nov 08 at 7:30 am
the only way i got this to work was with Flash CS4 and nothing else
Marc
13 Nov 08 at 7:32 am
Ok got it to work in Flex… just need to do alot of modifications to the project (like change the swc, then changing the way it compiles and then changing the version needed for the player)
Marc
13 Nov 08 at 7:39 am
ok .. forget it .. it just messes up the project.. so it works once .. then when you reopen the project.. flex cries about some stuff being invalid
Marc
13 Nov 08 at 7:42 am
ok … sorry last post i swear…
i have to tell flex compiler to juste require flash 10 and thats it.. it seems… got a guide that messed up the other test.. but now it works… thank you the code is great by the way
Marc
13 Nov 08 at 7:46 am
[...] can read more about this on Mike Chambers blog, there are also sample applications to [...]
Kun Janos around Adobe’s <Flex> & <Flash> » Blog Archive » Reading and Writing Local Files in Flash Player 10
28 Nov 08 at 12:18 am
[...] Files are a lot easier to work with in player 10 than I though they would be. Writing to a text file is as simple as fr.save(someString, someName) loading is also a lot less painful than I thought it might be. Mike Chambers has written a good getting started guide here. [...]
pixelrevision » Blog Archive » pixelbender and file creation
5 Dec 08 at 4:07 pm
[...] can read more about this on Mike Chambers blog, there are also sample applications to [...]
Reading and Writing Local Files in Flash Player 10 « Kun Janos around Adobe’s <Flex> and <Flash>
12 Jan 09 at 8:28 am
Being able to read and save files from Flash sounds great. I am a game programmer in Flash, but not being able to save files was strongly limiting the type of games I created (for example, creating an RPG was unthinkable until now). I know there are still the shared objects, but these files are hard to get by the average user, so transferring from computer to computer is a pain, and integratign with other apps, a wizard’s work. Not to mention that plenty of people keep erasing their cookies, etc. So I’m happy to know that reading and saving files will be possible / is possible from Flash.
If security is a concern, then I propose a few approaches:
- Files can only be saved in specific folders. Maybe a preset folder in the C: drive in windows, for instance. Maybe C:\flashdata This way everyone knows where it is, but can’t save elsewhere and do bad things, same for Linux and Mac OS. Saving in directories within that one would be ok. This way, no one can leak any file into a dangerous directory (such as the OS folder / directory)
- Limit the file extension to something predefined. Maybe .fd (flash data), so no one will try to save a .exe or anything of the sort (have flash simply not allow it), so if someone tries to pull a malicious executable, it simply will not launch.
It is only a matter of thinking a bit. Having the capability of writing and reading files from Flash is a great thing, and we should not give our backs to this possibility. By using some common sense, it can still be used safely and not be hacker-friendly.
Some other readers posted concerns that this would require flash to be visible. I think this could be addressed by only requiring it to be visible IF there will be any file saving or reading, and never otherwise.
Hope someone involved in the development of Flash Player 10, 11, etc. gets to read this. ;-)
SomeNick
11 Feb 09 at 1:04 pm
[...] ?????????Mike Chambers???????????http://www.mikechambers.com/blog/2008/08/20/reading-and-writing-local-files-in-flash-player-10/ [...]
Flash10?????? | CSDreamer's Blog
11 Mar 09 at 8:02 am
Mike,
Is is possible to locate a users home directory from a Flash standalone application when the application is not in the users directory? Or is a wrapper application(Zinc, mProjector, etc.) still the only way to achieve this? I’m hoping to avoid the wrapper if possible.
I would like to read/create a prefs file located somewhere in the users directory, I.E. Application Support.
John I.
12 Mar 09 at 9:35 am
[...] http://www.mikechambers.com/blog/2008/08/20/reading-and-writing-local-files-in-flash-player-10/ [...]
Flash Player 10. Cargar y salvar imágenes - blog.coconnut.com
14 May 09 at 12:51 pm
Is it possible to call the save() command from a loaded swf? We have a preloader swf that loads in a main swf. When we do this the save() function fails from the main swf. If we remove the preloader and just start with the main file, We can save. Any workaround for this?
scott
1 Jul 09 at 4:12 pm
hi..
load() is until 100MB.
Can you convert big size file to ByteArray ???
not Air.
YoungJae
25 Aug 09 at 5:44 pm
Hey…
I get the FileRefrence API, but have no save() method. Havent checked if pointing to Flash 10.
Francois
14 Oct 09 at 6:58 am
got it working, was using Flash 9.
thx for the great article
Francois
14 Oct 09 at 7:15 am
Hi Mike,
Tried to compile the 2 MXML you have given in Flex 3.
The first one produced 2 Compilation Errors.
fr.load();
&
var data:ByteArray = fr.data;
The Second one showed 1 comiplation Error
fr.save(inputField.text, DEFAULT_FILE_NAME);
I’m stumped. Can you check ‘em and revert back?
Cheers mate.
Sid
1 Nov 09 at 3:30 am
Hey Mike,
I understand the Compilation error of your MXML is due to the fact that my Flex 3 is NOT setup for FP10.
I work in Flex. My question is – if I set it up for FP10, will my new apps in Flex 3 still run in FP9 as well. If it doesn’t, it could spell disaster for me. Please advise.
Cheers mate.
Sid
1 Nov 09 at 3:54 am
Thank you soooooooooo much for sharing :)
Suma Gowda
24 Dec 09 at 9:46 pm
would you be kind enough to show me how to pass those values from a bytearray to a datagrid?…
miguel
3 Jan 10 at 9:24 pm