19 July 2004
A basic understanding of JSFL syntax, the Flash authoring environment, and familiarity with JavaScript.
All
The latest update to Macromedia Flash MX 2004 adds new file I/O capabilitiesto the JavaScript API (JSAPI). The shared library installed withthe Flash MX 2004 7.2 Updater exposes a new FLfile objectto JavaScript Flash (JSFL). This object contains 14 new functionsthat enable Flash developers to write Flash extensions that can access,modify, and remove files and folders on the local file system.
In this article I introduce you to the new functionality of the FileAPI and show you how to implement it in your JSFL scripts.
Note: This article discusses extending the functionality of the Flash authoring environment through the extensibility layer and JSFL. It does not apply to Macromedia Flash Player, or adding File I/O capabilities to SWF files.
The JSFL File API is provided in the form of an extension to the JSAPI. This extension is called a shared library and you can find it in the External Libraries subfolder of your Flash Configuration folder—the filename is FLfile.dll. The location of the Flash Configuration folder differs depending on the operating system installed on your computer. The following list identifies the location of the shared library file:
C:\Documents and Settings\<username>\Local Settings\Application Data\Macromedia\Flash MX 2004\<language>\Configuration\External Libraries\FLfile.dll
C:\Windows\Application Data\Macromedia\Flash MX 2004\<language>\Configuration\ExternalLibraries\FLfile.dll
Hard Drive/Users/<username>/Library/Application Support/Macromedia/Flash MX 2004/<language>/Configuration/ External Libraries\FLfile.dll
For your JSFL scripts to use the File API, Flash MX 2004 7.2 must be installed on the machine that executes the JSFL script.
Note: Don't confuse the shared libraries that contain symbols in your Flash documents with the JSAPI shared libraries. They are two totally different things.
The File API consists of 14 functions that you can use anywhere in your JSFL scripts. Each function is accessed as a static method of the FLfile object.
You don't need to create an instance of the FLfile object to access its methods. You access the functions directly through the FLfile object.
For example, one of the functions in the FLfile object is called createFolder, and as you would expect from a method with such a name, it creates a folder on the local file system. To use this method in your JSFL scripts you would use the following syntax:
FLfile.createFolder("file:///C:/myFolder");
All of the functions in the File API work with files or folders on the file system. Therefore, the functions in the File API always accept an argument that tells the function the location of the file or folder that will be affected. The location of the file or folder is expressed as a string in a form very similar to a website URL. It is called a file URI (Uniform Resource Identifier) and looks like this:
file:///<drive>/folder/anotherFolder/
For example, if you wanted to create a folder on the C drive called config, you would pass the following file URI to the createFolder method of the FLfile object:
file:///C:/config/
You can perform various file system operations with JSFL scripts. Some functionality may have different results on computers running Mac OS X. Tables 1 and 2 provide a complete rundown of what you can do with the File API. For your convenience, I've cross-referenced the actual function that will perform the operation you require.
| To do this | Use this function |
|---|---|
| Create a file | FLfile.write() |
| Write to a file | FLfile.write() |
| Add to a file | FLfile.write() |
| Read the contents of a file | FLfile.read() |
| Delete a file | FLfile.remove() |
| Copy a file | FLfile.copy() |
| Determine the existence of a file | FLfile.exists() |
| Get the size of a file | FLfile.getSize() |
| Get the date a file was created | FLfile.getCreationDateObj(), FLfile.getCreationDate() |
| Get the date a file was modified | FLfile.getModificationDateObj(), FLfile.getModificationDate() |
| Find out if a file is read-only | FLfile.getAttributes() |
| Find out if a file is hidden | FLfile.getAttributes() |
| Find out if a file is a system file | FLfile.getAttributes() |
| Make a file writable | FLfile.setAttributes() |
| Make a file hidden | FLfile.setAttributes() |
| Make a file visible | FLfile.setAttributes() |
| Make a file read-only | FLfile.setAttributes() |
| To do this | Use this function |
|---|---|
| Create a folder | FLfile.createFolder() |
| List the contents of a folder | FLfile.listFolder() |
| Delete a folder | FLfile.remove() |
| Determine the existence of a folder | FLfile.exists() |
| Get the date a folder was created | FLfile.getCreationDateObj(), FLfile.getCreationDate() |
| Get the date a folder was modified | FLfile.getModificationDateObj(), FLfile.getModificationDate() |
| Find out if a folder is read-only | FLfile.getAttributes() |
| Find out if a folder is hidden | FLfile.getAttributes() |
| Make a folder hidden | FLfile.setAttributes() |
| Make a folder visible | FLfile.setAttributes() |
| Make a folder read-only | FLfile.setAttributes() |
| Make a folder writable | FLfile.setAttributes() |
Note: All the File API functions can be used in JSFL scripts that are executed on a computer with Flash MX 2004 7.2 installed. Unfortunately, most of the File API methods do not function correctly when running under earlier releases of Flash MX 2004.
This section explains in detail the various File API functions.
You can use the copy method to copy a file to another location. This function accepts two arguments: The first argument is a file URI that specifies the location of the file you want to copy; the second argument is a file URI that specifies the location to which you want to copy the file.
The following example makes a backup copy of a configuration file named config.ini and places it inside the same directory in which it resides with a new name:
originalFileURI="file:///C:/Program Files/MyApp/config.ini";
newFileURI="file:///C:/Program Files/MyApp/config_backup.ini"
Flfile.copy(originalFileURI,newFileURI);
The copy method returns true if copying the file was successful; otherwise it returns false.
You can also use this method to rename a file by simply using it to copy a file, giving the copied file a new name, and then deleting the original file.
The read method can be used to get the contents of any file as a string. This function accepts one argument: a file URI that specifies the location of the file from which you would like to read the contents.
The following example reads the ActionScript code from a class file:
classFileURI="file:///C:/MyApplication/TextCarousel.as";
code=Flfile.read(classFileURI);
The read method returns the contents of the specified file as a string if it was successful, and null otherwise.
The write method can be used to write a string to a file. This function accepts three arguments. The first argument is a file URI that specifies the location of the file into which you want to write the specified string. The second argument specifies the string you want to write to the specified file. The third argument tells the function what to do if the specified file already exists; by default, the file is written over and the specified string is written to the new file. You can also tell the function to append the specified string to the contents of an already existing file by passing append as the value for the third argument. The third argument is not required.
The following example writes some basic stub code for an ActionScript class to a new class file:
classFileURI="file:///C:/MyApplication/TextCarousel.as";
code="import mx.core.UIObject\n"
code+="class TextCarousel extends UIObject\n{\n"
FLfile.write(classFileURI,code)
The following example adds some more ActionScript code to the class file of the previous example:
classFileURI="file:///C:/MyApplication/TextCarousel.as";
moreCode="\tfunction TextCarousel()\n{\n"
moreCode+="\t\t this.init()\n";
moreCode+="\t}\n"
moreCode+="}"
Flfile.write(classFileURI,moreCode,"append")
The write method returns true if the specified string was successfully written to the file; if not, it returns false.
The getSize method can be used to return the size of a file in bytes, as a number. This function accepts one argument: a file URI that specifies the location of the file you want to check.
The following example checks to see that the executable file for an application has not been modified by checking if the size of the file is the expected size:
mainAppLocation="file:///C:/Program Files/Macromedia/Flash MX 2004/flash.exe";
var expectedSize="13205504" //12.5 mb
if(Flfile.getSize(mainAppLocation) == expectedSize)
{
alert("This program is in its original state")
}
else
{
alert("Modifications have been made to this application")
}
The getSize method returns the size of the specified file in bytes as a number. If the file could not be found, then 0 is returned.
To convert bytes into kilobytes, you should divide its value by 1024 (there are 1024 bytes in one kilobyte):
alert((FLfile.getSize("file:///C:/WINNT/explorer.exe")/1024)+"kb")
The exists method can be used to determine the existence of a file or folder. Thisfunction accepts one argument: a file URI that specifies the location of a file thatyou are looking for.
The following example checks to see if a required configuration file exists. If it doesn'texist, then it is created:
configFileLocation="file:///C:/MyApplication/config.ini";
if(!FLfile.exists(configFileLocation))
{
FLfile.write(configFileLocation,"")
}
The exists method returns true if the specified file exists on the file system and false otherwise.
The createFolder method can be used to create a folder or a hierarchy of folders. This function accepts one argument: a file URI that specifies the location of the folder or series of folders that you want to create.
The following example creates a configuration folder, inside of which an application will create files that save the user's configuration settings:
applicationFolder="file:///C:/Program Files/Auto Save/"
FLfile.createFolder(applicationFolder+"/Configuration/")
classPath="controls.cellRenderers"
var folders=classPath.split(".")
var folderPath=folders.join("/")
var projectFolder="file:///C:/MyApplication"
FLfile.createFolder(projectFolder+"/"+folderPath+"/")
If any folder in the specified folder location does not exist, then it is created.
The createFolder method returns true if the folder or series of folders was created successfully. If not, it returns false.
The listFolder method can be used to retrieve an array containing the names of files or folders contained within a specified folder. The listFolder method accepts two arguments. The first argument is a file URI that specifies the location of the folder from which you want to retrieve a list of its contents. You can also specify a wildcard file mask in the file URI, which makes it possible to return only files or folders with specific characters in their name. The second, optional, argument specifies whether you want the function to return only the names of files that reside in the specified folder, or whether you want the function to return only the names of folders that are located in the specified folder. It can have two possible values:
files – Returns only the names of filesdirectories – Returns only the names of foldersIf you don't specify a value for the second argument, then the function will return the names of both the files and folders that reside in the specified folder.
The following example returns an array of the names of all the folders inside the Windows application folder and then outputs them to an alert window:
folderNames=FLfile.listFolder("file:///C:/WINNT","directories")
alert(folderNames.join("\n"))
To return only the names of folders that are located in the Windows application folder, you can pass the string "directories" as the value for the second argument.
The following example returns an array of the names of all the files in the Windows application folder and then outputs them to an alert window:
filenames=FLfile.listFolder("file:///C:/WINNT/","files")
alert(filenames.join("\n"))
To return only the names of files that reside in the Windows application folder, pass the string "files" as the value for the second argument.
The following example returns an array of the names of all the files and folders in the Windows application folder and then outputs them to an alert window:
contents=FLfile.listFolder("file:///C:/WINNT/")
alert(contents.join("\n"))
executables=FLfile.listFolder("file:///C:/WINNT/*.exe","files")
alert(executables.join("\n"))
The * wildcard character matches one or more characters in a filename.
The remove method can be used to remove a file or a folder that is not read-only from the local machine. If you attempt to delete a folder that contains files or folders, they will also be deleted. If any of those files or folders are read-only, then they will not be deleted—nor the containing folder. This function accepts one argument: a file URI that specifies the location of a file or a folder that you want to delete.
The following example deletes a configuration file created by an application:
if(FLfile.remove("file:///C:/MyApplication/config.ini"))
{
alert("Configuration file deleted")
}
FLfile.remove("file:///C:/MyApplication/Configuration/")
The remove method returns true if the file or folder was successfully deleted; if not, it returns false.
The getAttributes method can be used to determine whether a file or folder is read-only, hidden, or whether it belongs to the system. You can also use this method to determine whether a specified location is a folder. This function accepts one argument: a file URI that specifies the location of a file or folder from which you want to retrieve the attributes.
The following example retrieves the contents of a folder and determines whether any of the contents of the folder are read-only. If they are not, then it safely deletes the folder:
applicationFolder="file:///C:/MyApplication/"
function anyContentsReadOnly(folder)
{
var contents=FLfile.listFolder(folder)
var numContents=contents.length
var attributes
for(var f=0;f<numContents;++f)
{
attributes=FLfile.getAttributes(folder+contents[f])
if(attributes.indexOf("R") != -1) return true
}
return false
}
if(!anyContentsReadOnly(applicationFolder))
{
FLfile.remove(applicationFolder)
}
The getAttributes method returns a string, which can contain zero or more of the following characters:
R – Is read-onlyD – Is a directoryH – Is hidden (Windows only)S – Belongs to the system (Windows only)A – Is ready for archiving (Windows only)The returned string is formed in the order in which the attributes are listed above.
Using the getAttributes method on a file or folder that is a read-only system file will return the string RS. Similarly, using the getAttributes method on a file or folder that is read-only and hidden will return a string "RH".
If the specified file or folder does not exist, then null will be returned; if the specified file or folder has no attributes, then an empty string is returned.
The setAttributes method can be used to make a file or folder is read-only, writable, hidden, or visible. This function accepts two arguments. The first argument is a file URI that specifies the location of a file or folder to which you want to set the specified attributes. The second argument is a string that can have one of eight possible values:
R – Make a specified file or folder read-onlyW – Make a specified file or folder writableH – Make a specified file or folder hidden (Windows only)V – Make a specified file or folder visible (Windows only)RH – Make a specified file or folder read-only and hiddenRV – Make a specified file or folder read-only and visibleWH – Make a specified file or folder writable and hiddenWV – Make a specified file or folder writable and visibleFor obvious reasons, you cannot make a file or folder read-only and writable at the same time. You also cannot make a file or folder hidden and visible at the same time. Only the attributes you specify are updated for the specified file or folder; all the other attributes of the file or folder remain the same.
The following example retrieves the contents of a folder and determines if any of the contents of the folder are read-only. If they are, then they are made writable so the folder can be deleted:
applicationFolder="file:///C:/MyApplication/"
function makeFolderContentsWritable(folder)
{
var contents=FLfile.listFolder(folder)
var numContents=contents.length
var attributes
for(var f=0;f<numContents;++f)
{
attributes=FLfile.getAttributes(folder+contents[f])
if(attributes.indexOf("R") != -1)
{
FLfile.setAttributes(folder+contents[f],"R")
}
}
}
makeFolderContentsWritable(applicationFolder)
FLfile.remove(applicationFolder)
The getAttributes method returns true if the attributes of the specified file or folder were set successfully, and false otherwise.
The getCreationDate method can be used to determine the number of units that have elapsed between the time the file or folder was created and the base time. The base time and units are platform-independent. On Windows the base time is January 1, 1600, and the units are 100 nanoseconds (1000th of a millisecond).
The following example determines whether a file has been modified since it was created:
fileURI="file:///C:/MyApplication/StateEngine.asp";
var creationTime=FLfile.getCreationDate(fileURI)
var modificationTime=FLfile.getModificationDate(fileURI)
if(modificationTime > creationTime)
{
alert("The file has been modified since it was created")
}
else
{
alert("The file is in the state it was when it was created")
}
The getCreationDate method returns a string containing a hexadecimal number if the specified file or folder exists, and false otherwise.
The getModificationDate method can be used to find out the number of units that have elapsed between the time the file or folder was last modified and the base time. The base time and units are platform-independent. On Windows the base time is January 1, 1600, and the units are 100 nanoseconds (1000th of a millisecond).
The following example compares the modification dates of two files and determines which of the two was last modified:
file1="file:///C:/MyApplication/StateEngine.as"
file2="file:///C:/MyApplication/StateController.as"
modificationTime1=FLfile.getModificationDate(file1)
modificationTime2=FLfile.getModificationDate(file2)
if(modificationTime1 > modificationTime2)
{
alert("File 2 is older than File 1")
}
else if(modificationTime1 < modificationTime2)
{
alert("File 1 is older than File 2")
}
else
{
alert("File 1 and File 2 were saved at the same time")
}
The getModificationDate method returns a string containing a hexadecimal number if the specified file or folder exists, and false otherwise.
The getModificationDateObj method functions in the same way as the getModificationDate method, with the exception that it returns a JSFL Date object as opposed to a hexadecimal string.
The getCreationDateObj method functions in the same way as the getCreationDate method except that it returns a JSFL Date object as opposed to a hexadecimal string.
| 04/23/2012 | Auto-Save and Auto-Recovery |
|---|---|
| 04/23/2012 | Open hyperlinks in new window/tab/pop-up ? |
| 04/21/2012 | PNG transparencies glitched |
| 04/01/2010 | Workaround for JSFL shape selection bug? |
| 02/13/2012 | Randomize an array |
|---|---|
| 02/11/2012 | How to create a Facebook fan page with Flash |
| 02/08/2012 | Digital Clock |
| 01/18/2012 | Recording webcam video & audio in a flv file on local drive |