Working with File objects in OpenFL
A File object is a pointer to a file or directory in the file system.
The File class extends the FileReference class. The FileReference class, which is available in web browsers as well as in native applications, represents a pointer to a file. The File class adds properties and methods that are not exposed in web browsers, due to security considerations.
About the File class
You can use the File class for the following:
Getting the path to special directories, including the user directory, the user's documents directory, the directory from which the application was launched, and the application directory
Coping files and directories
Moving files and directories
Deleting files and directories (or moving them to the trash)
Listing files and directories contained in a directory
Creating temporary files and folders
Once a File object points to a file path, you can use it to read and write file data, using the FileStream class.
A File object can point to the path of a file or directory that does not yet exist. You can use such a File object in creating a file or directory.
Paths of File objects
Each File object has two properties that each define its path:
Property | Description |
---|---|
nativePath |
Specifies the platform-specific path to a file. For example, on Windows a path might be "c:\Sample directory\test.txt" whereas on macOS it could be "/Sample directory/test.txt". A nativePath property uses the backslash (\ character as the directory separator character on Windows, and it uses the forward slash (/) character on macOS and Linux. |
url |
This may use the file URL scheme to point to a file. For example, on Windows a path might be "file:///c:/Sample%20directory/test.txt" whereas on macOS it could be "file:///Sample%20directory/test.txt". The runtime includes other special URL schemes besides file and are described in Supported OpenFL URL schemes |
The File class includes static properties for pointing to standard directories on macOS, Windows, and Linux. These properties include:
File.applicationStorageDirectory
— a storage directory unique to each installed OpenFL application. This directory is an appropriate place to store dynamic application assets and user preferences. Consider storing large amounts of data elsewhere.On Android and iOS, the application storage directory is removed when the application is uninstalled or the user chooses to clear application data, but this is not the case on other platforms.
File.applicationDirectory
— the directory where the application is installed (along with any installed assets). On some operating systems, the application is stored in a single package file rather than a physical directory. In this case, the contents may not be accessible using the native path. The application directory is read-only.File.desktopDirectory
— the user's desktop directory. If a platform does not define a desktop directory, another location on the file system is used.File.documentsDirectory
— the user's documents directory. If a platform does not define a documents directory, another location on the file system is used.File.userDirectory
— the user directory. If a platform does not define a user directory, another location on the file system is used.
Note: When a platform does not define standard locations for desktop, documents,
or user directories, File.documentsDirectory
, File.desktopDirectory
, and
File.userDirectory
may reference the same directory.
These properties have different values on different operating systems. For
example, macOS and Windows each have a different native path to the user's
desktop directory. However, the File.desktopDirectory
property points to an
appropriate directory path on every platform. To write applications that work
well across platforms, use these properties as the basis for referencing other
directories and files used by the application. Then use the resolvePath()
method to refine the path. For example, this code points to the preferences.xml
file in the application storage directory:
var prefsFile:File = File.applicationStorageDirectory;
prefsFile = prefsFile.resolvePath("preferences.xml");
Although the File class lets you point to a specific file path, doing so can
lead to applications that do not work across platforms. For example, the path
C:\Users\joe\ only works on Windows. For these reasons, it is best to use the
static properties of the File class, such as File.documentsDirectory
.
Common directory locations
Platform |
Directory type |
Typical file system location |
---|---|---|
Linux |
Application |
/opt/<Program Name>/share |
Application-storage |
/home/<userName>/.local/share/<Program Name> |
|
Desktop |
/home/<userName>/Desktop |
|
Documents |
/home/<userName>/Documents |
|
Temporary |
/tmp/ofl-<randomString>.tmp |
|
User |
/home/<userName> |
|
macOS |
Application |
/Applications/<Program Name>.app/Contents/Resources |
Application-storage |
/Users/<userName>/Library/Application Support/<Program Name> |
|
Desktop |
/Users/<userName>/Desktop |
|
Documents |
/Users/<userName>/Documents |
|
Temporary |
/var/folders/ofl-<randomString>.tmp |
|
User |
/Users/<userName> |
|
Windows |
Application |
C:\Program Files\<Program Name> |
Application-storage |
C:\Users\<userName>\AppData\Roaming\<Company Name>\<Program Name> |
|
Desktop |
C:\Users\<userName>\Desktop |
|
Documents |
C:\Users\<userName>\Documents |
|
Temporary |
C:\Users\<userName>\AppData\Local\Temp\ofl-<randomString>.tmp |
|
User |
C:\Users\<userName> |
The actual native paths for these directories vary based on the operating system
and computer configuration. The paths shown in this table are typical examples.
You should always use the appropriate static File class properties to refer to
these directories so that your application works correctly on any platform. In
an actual OpenFL application, the values in angle brackets, like
<Program Name>
and <userName>
, are taken either from the operating system or
the OpenFL project.xml file.
Pointing a File object to a directory
There are different ways to set a File object to point to a directory.
Pointing to the user's home directory
You can point a File object to the user's home directory. The following code sets a File object to point to an OpenFL Test subdirectory of the home directory:
var file:File = File.userDirectory.resolvePath("OpenFL Test");
Pointing to the user's documents directory
You can point a File object to the user's documents directory. The following code sets a File object to point to an OpenFL Test subdirectory of the documents directory:
var file:File = File.documentsDirectory.resolvePath("OpenFL Test");
Pointing to the desktop directory
You can point a File object to the desktop. The following code sets a File object to point to an OpenFL Test subdirectory of the desktop:
var file:File = File.desktopDirectory.resolvePath("OpenFL Test");
Pointing to the application storage directory
You can point a File object to the application storage directory. For every OpenFL application, there is a unique associated path that defines the application storage directory. This directory is unique to each application and user. You can use this directory to store user-specific, application-specific data (such as user data or preferences files). For example, the following code points a File object to a preferences file, prefs.xml, contained in the application storage directory:
var file:File = File.applicationStorageDirectory;
file = file.resolvePath("prefs.xml");
The application storage directory location is typically based on the user name
and the application ID. The following file system locations are given here to
help you debug your application. You should always use the
File.applicationStorage
property or app-storage:
URI scheme to resolve files
in this directory:
On macOS — In the user home directory:
/Users/<userName>/Library/Application Support/<Program Name>
For example:
/Users/babbage/Library/Application Support/My Test App
On Windows — In the user home directory, in:
C:\Users\<userName>\AppData\Roaming\<Company Name>\<Program Name>
For example:
C:\Users\babbage\Application Data\My Company\My Test App
On Linux — In the user home directory:
/home/<userName>/.local/share/<Program Name>
For example:
/home/babbage/.local/share/My Test App
Note: If an application has a publisher ID, then the publisher ID is also used as part of the path to the application storage directory.
Pointing to the application directory
You can point a File object to the directory in which the application was
installed, known as the application directory. You can reference this directory
using the File.applicationDirectory
property. You can use this directory to
examine the application descriptor file or other resources installed with the
application. For example, the following code points a File object to a directory
named images in the application directory:
var dir:File = File.applicationDirectory;
dir = dir.resolvePath("images");
Pointing to the file system root
The File.getRootDirectories()
method lists all root volumes, such as C: and
mounted volumes, on a Windows computer. On macOS and Linux, this method always
returns the unique root directory for the machine (the "/" directory).
Note: The root of the file system is not readable on Android. A File object
referencing the directory with the native path, "/", is returned, but the
properties of that object do not have accurate values. For example,
spaceAvailable
is always 0.
Pointing to an explicit directory
You can point the File object to an explicit directory by setting the
nativePath
property of the File object, as in the following example (on
Windows):
var file:File = new File();
file.nativePath = "C:\\OpenFL Test";
Important: Pointing to an explicit path this way can lead to code that does
not work across platforms. For example, the previous example only works on
Windows. You can use the static properties of the File object, such as
File.applicationStorageDirectory
, to locate a directory that works
cross-platform. Then use the resolvePath()
method (see the next section) to
navigate to a relative path.
Navigating to relative paths
You can use the resolvePath()
method to obtain a path relative to another
given path. For example, the following code sets a File object to point to an
OpenFL Test subdirectory of the user's home directory:
var file:File = File.userDirectory;
file = file.resolvePath("OpenFL Test");
For more information, see Modifying File paths.
Letting the user browse to select a directory
The File class includes the browseForDirectory()
method, which presents a
system dialog box in which the user can select a directory to assign to the
object. The browseForDirectory()
method is asynchronous. The File object
dispatches a select
event if the user selects a directory and clicks the Open
button, or it dispatches a cancel
event if the user clicks the Cancel button.
For example, the following code lets the user select a directory and outputs the directory path upon selection:
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.filesystem.File;
class FileBrowseForDirectoryExample extends Sprite
{
private var file:File;
public function new()
{
super();
file = new File();
file.addEventListener(Event.SELECT, dirSelected);
file.browseForDirectory("Select a directory");
}
private function dirSelected(e:Event):Void
{
trace(file.nativePath);
}
}
Note: On Android, the browseForDirectory()
method is not supported. Calling
this method has no effect; a cancel event is dispatched immediately. To allow
users to select a directory, use a custom, application-defined dialog, instead.
Pointing to the directory from which the application was invoked
You can get the directory location from which an application is invoked, by
checking the currentDirectory
property of the InvokeEvent object dispatched
when the application is invoked.
Pointing a File object to a file
There are different ways to set the file to which a File object points.
Pointing to an explicit file path
Important: Pointing to an explicit path can lead to code that does not work
across platforms. For example, the path C:/foo.txt only works on Windows. You
can use the static properties of the File object, such as
File.applicationStorageDirectory
, to locate a directory that works
cross-platform. Then use the resolvePath()
method (see
Modifying File paths) to navigate to a relative path.
You can also use the nativePath
property of a File object to set an explicit
path. For example, the following code, when run on a Windows computer, sets a
File object to the test.txt file in the OpenFL Test subdirectory of the C:
drive:
var file:File = new File();
file.nativePath = "C:/OpenFL Test/test.txt";
You can also pass this path to the File()
constructor function, as in the
following:
var file:File = new File("C:/OpenFL Test/test.txt");
Use the forward slash (/) character as the path delimiter for the nativePath
property. On Windows, you can also use the backslash (\ character, but doing so
leads to applications that do not work across platforms.
For more information, see Modifying File paths.
Enumerating files in a directory
You can use the getDirectoryListing()
method of a File object to get an array
of File objects pointing to files and subdirectories at the root level of a
directory. For more information, see
Enumerating directories.
Letting the user browse to select a file
The File class includes the following methods that present a system dialog box in which the user can select a file to assign to the object:
browseForOpen()
browseForSave()
browseForOpenMultiple()
These methods are each asynchronous. The browseForOpen()
and browseForSave()
methods dispatch the select event when the user selects a file (or a target
path, in the case of browseForSave()). With the browseForOpen()
and
browseForSave()
methods, upon selection the target File object points to the
selected files. The browseForOpenMultiple
() method dispatches a
selectMultiple
event when the user selects files. The selectMultiple
event
is of type FileListEvent, which has a files
property that is an array of File
objects (pointing to the selected files).
For example, the following code presents the user with an "Open" dialog box in which the user can select a file:
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.filesystem.File;
import openfl.net.FileFilter;
class FileBrowseForOpenExample extends Sprite
{
private var fileToOpen:File;
public function new()
{
super();
fileToOpen = File.documentsDirectory;
selectTextFile(fileToOpen);
}
private function selectTextFile(root:File):Void
{
var txtFilter:FileFilter = new FileFilter("Text", "*.hx;*.css;*.html;*.txt;*.xml");
root.browseForOpen("Open", [txtFilter]);
root.addEventListener(Event.SELECT, fileSelected);
}
private function fileSelected(event:Event):Void
{
trace(fileToOpen.nativePath);
}
}
If the application has another browser dialog box open when you call a browse method, the runtime throws an Error exception.
Note: On Android, only image, video, and audio files can be selected with the
browseForOpen()
and browseForOpenMultiple()
methods. The browseForSave()
dialog also displays only media files even though the user can enter an
arbitrary filename. For opening and saving non-media files, you should consider
using custom dialogs instead of these methods.
Modifying File paths
You can also modify the path of an existing File object by calling the
resolvePath()
method or by modifying the nativePath
or url
property of the
object, as in the following examples (on Windows):
import openfl.display.Sprite;
import openfl.filesystem.File;
class ModifyFilePathExample extends Sprite
{
public function new()
{
super();
var file1:File = File.documentsDirectory;
file1 = file1.resolvePath("OpenFL Test");
trace(file1.nativePath); // C:\Users\userName\My Documents\OpenFL Test
var file2:File = File.documentsDirectory;
file2 = file2.resolvePath("..");
trace(file2.nativePath); // C:\Users\userName
var file3:File = File.documentsDirectory;
file3.nativePath += "/subdirectory";
trace(file3.nativePath); // C:\Users\userName\My Documents\subdirectory
}
}
When using the nativePath
property, use the forward slash (/) character as the
directory separator character. On Windows, you can use the backslash (\
character as well, but you should not do so, as it leads to code that does not
work cross-platform.
Supported OpenFL URL schemes
In OpenFL, you can use any of the following URL schemes in defining the url
property of a File object:
URL scheme |
Description |
---|---|
file |
Use to specify a path relative to the root of the file system. For example:
The URL standard specifies that a file URL takes the form file://<host>/<path>. As a special case, <host> can be the empty string, which is interpreted as "the machine from which the URL is being interpreted." For this reason, file URLs often have three slashes (///). |
app |
(Since OpenFL 9.4) Use to specify a path relative to the root directory of the installed application (the directory that contains the application.xml file for the installed application). For example, the following path points to an images subdirectory of the directory of the installed application:
|
app-storage |
(Since OpenFL 9.4) Use to specify a path relative to the application store directory. For each installed application, OpenFL defines a unique application store directory, which is a useful place to store data specific to that application. For example, the following path points to a prefs.xml file in a settings subdirectory of the application store directory:
|
Finding the relative path between two files
You can use the getRelativePath()
method to find the relative path between two
files:
import openfl.display.Sprite;
import openfl.filesystem.File;
class FileGetRelativePathExample1 extends Sprite
{
public function new()
{
super();
var file1:File = File.documentsDirectory.resolvePath("OpenFL Test");
var file2:File = File.documentsDirectory;
file2 = file2.resolvePath("OpenFL Test/bob/test.txt");
trace(file1.getRelativePath(file2)); // bob/test.txt
}
}
The second parameter of the getRelativePath()
method, the useDotDot
parameter, allows for ..
syntax to be returned in results, to indicate parent
directories:
import openfl.display.Sprite;
import openfl.filesystem.File;
class FileGetRelativePathExample2 extends Sprite
{
public function new()
{
super();
var file1:File = File.documentsDirectory;
file1 = file1.resolvePath("OpenFL Test");
var file2:File = File.documentsDirectory;
file2 = file2.resolvePath("OpenFL Test/bob/test.txt");
var file3:File = File.documentsDirectory;
file3 = file3.resolvePath("OpenFL Test/susan/test.txt");
trace(file2.getRelativePath(file1, true)); // ../..
trace(file3.getRelativePath(file2, true)); // ../../bob/test.txt
}
}
Obtaining canonical versions of file names
File and path names are not case sensitive on Windows and macOS. In the following, two File objects point to the same file:
File.documentsDirectory.resolvePath("test.txt");
File.documentsDirectory.resolvePath("TeSt.TxT");
However, documents and directory names do include capitalization. For example, the following assumes that there is a folder named OpenFL Test in the documents directory, as in the following examples:
import openfl.display.Sprite;
import openfl.filesystem.File;
class FileCanonicalizeExample1 extends Sprite
{
public function new()
{
super();
var file:File = File.documentsDirectory.resolvePath("OpenFL test");
trace(file.nativePath); // ... OpenFL test
file.canonicalize();
trace(file.nativePath); // ... OpenFL Test
}
}
The canonicalize()
method converts the nativePath
object to use the correct
capitalization for the file or directory name. On case sensitive file systems
(such as Linux), when multiple files exists with names differing only in case,
the canonicalize()
method adjusts the path to match the first file found (in
an order determined by the file system).
You can also use the canonicalize()
method to convert short file names ("8.3"
names) to long file names on Windows, as in the following examples:
import openfl.display.Sprite;
import openfl.filesystem.File;
class FileCanonicalizeExample2 extends Sprite
{
public function new()
{
super();
var path:File = new File();
path.nativePath = "C:\\OpenFL~1";
path.canonicalize();
trace(path.nativePath); // C:\OpenFL Test
}
}
Opening files with the default system application
You can open a file using the application registered by the operating system to
open it. For example, an OpenFL application can open a DOC file with the
application registered to open it. Use the openWithDefaultApplication()
method
of a File object to open the file. For example, the following code opens a file
named test.doc on the user's desktop and opens it with the default application
for DOC files:
import openfl.display.Sprite;
import openfl.filesystem.File;
class FileOpenWithDefaultApplicationExample1 extends Sprite
{
public function new()
{
super();
var file:File = File.desktopDirectory;
file = file.resolvePath("test.doc");
file.openWithDefaultApplication();
}
}
Note: On Linux, the file's MIME type, not the filename extension, determines the default application for a file.
The following code lets the user navigate to an mp3 file and open it in the default application for playing mp3 files:
import openfl.display.Sprite;
import openfl.events.Event;
import openfl.filesystem.File;
import openfl.net.FileFilter;
class FileOpenWithDefaultApplicationExample2 extends Sprite
{
private var file:File;
public function new()
{
super();
file = File.documentsDirectory;
var mp3Filter:FileFilter = new FileFilter("MP3 Files", "*.mp3");
file.addEventListener(Event.SELECT, fileSelected);
file.browseForOpen("Open", [mp3Filter]);
}
private function fileSelected(e:Event):Void
{
file.openWithDefaultApplication();
}
}
You cannot use the openWithDefaultApplication()
method with files located in
the application directory.
Note: This limitation does not exist for an OpenFL application installed using a native installer (an extended desktop application).