The Filesystem

0
233

The filesystem should be familiar to anyone who owns a computer. It is responsible for the hierarchical organization of files and projects, with the option to read, write, move, and delete files. In AIR for Android, files can only be created and manipulated in the application storage directory or on the SD card.

The File class belongs to the flash.filesystem package and inherits from the FileRefer ence class. It represents the path to a directory or a file, regardless of whether the directory or file exists or has not yet been created.

You can create a File object to the path of the file you want to access, here the application storage area. The resolvePath function creates the path from the current location which is the .swf file that is currently running:

import flash.filesystem.File;
var file:File
= File.applicationStorageDirectory.resolvePath(“hello.txt”);

Data is read or written using FileStream. Create it, open it, and close it after the operation is complete.

The FileStream method you should use depends on the type of data you are encoding. For text files, use readUTFBytes and writeUTFBytes. For a ByteArray, use readBytes and writeBytes, and so on. To get a complete list of methods, refer to http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/filesystem/FileStream.html.

Writing data to the file

Use the FileMode.WRITE method to write data to the file. In the following example, we are creating a folder if one does not already exist, and then we are creating a file in the folder:

import flash.filesystem.File;
import flash.filesystem.FileStream;
import flash.filesystem.FileMode;
var folder:File
= File.applicationStorageDirectory.resolvePath(“greetings”);
if (!folder.exists) {
folder.createDirectory();
}
var file:File = folder.resolvePath(“hello.txt”);

Note that although a reference to the new file has been created, the file will not exist until data is saved in it. Let’s write a simple string:

var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeUTFBytes(“Can you hear me?”);
fileStream.close();

Reading a file

Use the FileMode.READ method to read a file. In the following example, if the file doesn’t exist, we don’t need to read its data:

var file:File
= File.applicationStorageDirectory.resolvePath(“greetings/hello.txt”);
if (!file.exists) {
return;
}
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var string:String = fileStream.readUTFBytes(fileStream.bytesAvailable);
fileStream.close();
trace(string); // Can you hear me?

Deleting a file

Let’s delete the file first:

var file:File
= File.applicationStorageDirectory.resolvePath(“greetings/hello.txt”);
if (file.exists) {
file.deleteFile();
}

Now let’s delete the directory. Note the boolean passed in the deleteDirectory function. This is to prevent errors. If the boolean is set to true, the folder is deleted only if the directory exists:

var folder:File
= File.applicationStorageDirectory.resolvePath(“greetings”);
folder.deleteDirectory(true);

Choosing between synchronous and asynchronous mode

You have a choice of synchronous or asynchronous mode (fileStream open or openA sync). The former uses the application’s main thread, so the application does not execute any other process until a command is completed. Use trace catch to capture any errors. The latter uses a different thread and runs in the background. You need to set listeners to be notified when the command is in progress or completed. Only one mode can be used at a time.

Asynchronous mode is often preferred for mobile development. Choosing one method over the other is also a function of how large the data set is, as well as if the saved data is needed in the current state of your application and the desired user experience.

The write and read examples shown earlier use a synchronized method. To trace errors, use a try catch statement:

try {
var string:String = fileStream.readUTFBytes(fileStream.bytesAvailable);
fileStream.close();
} catch(error:Error) {
trace(error.message);
}
In this asynchronous example, we read a text file and store it when it is received in its
entirety:
import flash.events.Event;
import flash.events.ProgressEvent;
var fileStream:FileStream;
var file:File
= File.applicationStorageDirectory.resolvePath(“hello.txt”);
if (!file.exists) {
return;
}
fileStream = new FileStream();
fileStream.addEventListener(ProgressEvent.PROGRESS, onProgress);
fileStream.addEventListener(Event.COMPLETE, onComplete);
fileStream.openAsync(file, FileMode.READ);
function onProgress(event:ProgressEvent):void {
trace(fileStream.bytesAvailable);
}
function onComplete(event:Event):void {
fileStream.removeEventListener(ProgressEvent.PROGRESS, onProgress);
fileStream.removeEventListener(Event.COMPLETE, onComplete);
var bytes:uint = fileStream.bytesAvailable;
fileStream.close();
}

Writing data and saving it to temporary files

You can write and save data to a temporary directory or file. The data is saved to the application cache. This method is particularly useful if you have data you want to temporarily save during the life of the application while keeping memory free. You can create a directory or a file:

var tempDirectory:File = File.createTempDirectory();
var tempFile:File = File.createTempFile();
trace(tempDirectory.nativePath, tempDirectory.isDirectory);
trace(tempFile.nativePath, tempFile.isDirectory);

Keep a variable reference to the data while the application is running, and delete the file when the application quits. If you want to make the cache data persistent, save its path using its nativePath property, and save its name using its name property, in a SharedObject or another file in the application storage directory. Finally, another good place to save temporary files is the SD card:

tempFile.deleteFile();
tempDirectory.deleteFile();

Unlike AIR on the desktop, when files are deleted they are removed immediately because the device doesn’t have a trash folder. The following command gives the same result as the ones shown earlier:

tempFile.moveToTrash();
tempDirectory.moveToTrash();

In addition to these features, you can also add data to the end of a file; when updating the file, you can read it and write to it at the same time. Also useful is the ability to copy files and folders and move them to another location. You can use this technique to move some the application assets to the SD card. Note, however, that you should never delete any files that came installed with your application, because that will invalidate it.