When building Flash apps or games there is very often a need to save some user data. It might be a player's progress in a game or some work done in an application. Usually online application data is being kept in a database and desktop apps are saving to a file on a hard drive. Flash also allows saving to shared objects, so called Flash's cookie files but there is a limit of size set by an operating system and some browsers or anti-viruses may clear them periodically effectively erasing users saved data. While for desktop apps developers choose Adobe AIR, which allows deeper integration with operating systems, not many people know that since Flash Player 10 there is also an option of saving and loading data from a file. In this quick article I will give you a code example of how this feature could be use along with JSON and ByteArrays to effectively save your data to a file.
So I was working on an educational application for teachers and one of the requirements was that they should have an option to load and save data to a file what would allow them exchanging data files between themselves. Amount of data was rather huge as among other data it consisted of x and y coordinates representing drawings done on a special canvas. I created a class containing public properties representing these x and y values stored in an array and other information like color and thickness of a stroke. Every time a user creates a new line, a new object of that class is being created and stored in an array, let's call it main array. When pressed a save button, that main array is serialised using JSON library, this means it is represented in a form of string. I also create another string containing information about the version of the application, date when the data is being exported and title of the export that a teacher provides when clicking the save button. Next using these strings and their lengths values I'm creating and populating a byte array. Before saving I'm also compressing it to minimise a file size and finally whole content of the byte array is being saved to a file. Loading a file is a very similar operation with all the steps reversed ;). Enough talking, let's have a look to the code, all important things are commented to give you a better explanation. Bear in mind that this is not a complete code to copy and paste as I just provide here pieces illustrating the whole idea.
This is a class that stores information about each drawing. I put it here to show you what sort of objects you could serialise and save to a file.
Then another class calles ActionsRecorder has a property mActionsArray containing instances of the ActionPen class and methods to serialise and de-serialise this data. To keep things simple I'm not providing the classes to create or recreate the ActionPen objects with drawing data here. As for JSON, if you are going to use build methods to the FP11 (and you should as there are more opitimal than as3corelib's JSON), use JSON.parse() instead of decode and JSON.stringify() instead of encode.
JSON encoded version of the mActionsArray would look like this:
Next in the other part of the application I keep method to use export string from ActionsRecorder to save it to a file and another method to read it from a file and send it to ActionsRecorder to import it. There are two important things to note here, one is that Flash Player can't automatically save or read from a file. Methods that are creating file reference objects are required to receive the MouseEvent in order to get access to a file system. The second restriction is that you can't specify any folder where that file is to be saved, it will be defaulted to a desktop and user will need to manually select a location in a browse window. Both are caused by security reasons, just imagine what would happen if your app created an exe file and saved it in the startup folder or accessed operating system configuration files without letting the user know about it. Forcing to use MouseEvent, the user has control that there is something being saved or opened for some reason.
So somewhere on the stage there are two buttons for import and export and here are the methods that are event handlers for them. First let's have a look on saving:
And for loading in addition for a mouse handler method for import button we also have another one for loading data:
So that's it. Of course the final code would have some data validation to make sure that data imported is correct. It could be an additional integer in byte array with a total number of bytes. If these two values didn't match we would know that something wrong happened to the file.
And here is a simple example how this looks in practice. First populate the array (represented by the list component) and export to a file. Next you can refresh the page and import the file to see the list populated again. Also open the saved file in a file editor to have a look at the binary content.