W3C

File API: Directories and System

W3C Working Draft 26 October 2010

This version:
http://www.w3.org/TR/2010/WD-file-system-api-20101026/
Latest published version:
http://www.w3.org/TR/file-system-api/
Latest editor's draft:
http://dev.w3.org/2009/dap/file-system/file-dir-sys.html
Editor:
Eric Uhrhane, Google

Abstract

This specification defines an API to navigate file system hierarchies, and defines a means by which a user agent may expose sandboxed sections of a user's local filesystem to web applications. It builds on [FILE-WRITER], which in turn built on [FILE-API], each adding a different kind of functionality.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

This document was published by the WebApps Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives). All feedback is welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words must, must not, required, should, should not, recommended, may, and optional in this specification are to be interpreted as described in [RFC2119].

This specification defines conformance criteria that apply to a single product: a user agent that implements the interfaces that it contains.

2. Introduction

This section is non-normative.

This API is intended to satisfy client-side-storage use cases not well served by databases. These are generally applications that involve large binary blobs and/or share data with applications outside of the browser.

It is intended to be minimal in extent, but sufficiently powerful that easy-to-use libraries may be built on top of it.

2.1 Use Cases

  1. Persistent uploader
    • When a file or directory is selected for upload, it copies it into a local sandbox and uploads a chunk at a time.
    • It can restart uploads after browser crashes, network interruptions, etc.
  2. Video game or other app with lots of media assets
    • It downloads one or several large tarballs, and expands them locally into a directory structure.
    • The same download should work on any operating system.
    • It can manage prefetching just the next-to-be-needed assets in the background, so going to the next game level or activating a new feature doesn't require waiting for a download.
    • It uses those assets directly from its local cache, by direct file reads or by handing local URIs to image or video tags, WebGL asset loaders, etc.
    • The files may be of arbitrary binary format.
    • On the server side, a compressed tarball will often be much smaller than a collection of separately-compressed files. Also, 1 tarball instead of 1000 little files will involve fewer seeks, all else being equal.
  3. Audio/Photo editor with offline access or local cache for speed
    • The data blobs are potentially quite large, and are read-write.
    • It may want to do partial writes to files (ovewriting just the ID3/EXIF tags, for example).
    • The ability to organize project files by creating directories would be useful.
    • Edited files should be accessable by client-side applications [iTunes, Picasa].
  4. Offline video viewer
    • It downloads large files (>1GB) for later viewing.
    • It needs efficient seek + streaming.
    • It must be able to hand a URI to the video tag.
    • It should enable access to partly-downloaded files e.g. to let you watch the first episode of the DVD even if your download didn't complete before you got on the plane.
    • It should be able to pull a single episode out of the middle of a download and give just that to the video tag.
  5. Offline Web Mail Client
    • Downloads attachments and stores them locally.
    • Caches user-selected attachments for later upload.
    • Needs to be able to refer to cached attachments and image thumbnails for display and upload.
    • Should be able to trigger the UA's download manager just as if talking to a server.
    • Should be able to upload an email with attachments as a multipart post, rather than sending a file at a time in an XHR.

2.2 Examples

function useAsyncFS(fs) {
  // see getAsText example in [FILE-API].
  fs.root.getFile("already_there.txt", null, function (f) {
    getAsText(f.file());
  });

  // But now we can also write to the file; see [FILE-WRITER].
  fs.root.getFile("logFile", {create: true}, function (f) {
    f.createWriter(writeDataToLogFile);
  });
}

// In the DOM or worker context:

requestFileSystem(false, 1024 * 1024, function(fs) {
  useAsyncFS(fs);
});

// In a worker:

var tempFS = requestFileSystem(false, 1024 * 1024);
var logFile = tempFS.root.getFile("logFile", {create: true});
var writer = logFile.createWriter();
writer.seek(writer.length);
writeDataToLogFile(writer);

3. Data Persistence and accessing the API

3.1 Temporary vs. Persistent Storage

This section is non-normative.

An application can request temporary or persistent storage space. Temporary storage may be easier to get, at the UA's discretion [looser quota restrictions, available without prompting the user], but the data stored there may be deleted at the UA's convenience, e.g. to deal with a shortage of disk space.

Conversely, once persistent storage has been granted, data stored there by the application should not be deleted by the UA without user intervention. The application may of course delete it at will. The UA should require permission from the user before granting persistent storage space to the application.

This API specifies the standard origin isolation in a filesystem context, along with persistence of data across invocations. Applications will likely use temporary storage for caching, and if it's still around from a previous session, it is often useful. Persistent data, on the other hand, is useless if you can't access it again the next time you're invoked. However, even persistent data may be deleted manually by the user [either through the UA or via direct filesystem operations].

3.2 Restrictions

FileSystem and FileSystemSync objects returned by requestFileSystem must have the following properties:

Do we need to mandate that the temporary and persistent filesystems be disjoint?

3.3 Security Considerations

This section is non-normative.

Because this API may allow untrusted code to read and write parts of a user's hard drive, there are a number of security and privacy issues that must be dealt with. Risks to the user include:

As with any other client-side storage, filesystem access allows for cookie-resurrection attacks. UAs will likely wish to present the option of clearing it when the user clears any other origin-specific storage, blocking access to it when cookies are blocked, etc. This is especially important if temporary storage space is permitted by default without explicit user permission.

3.4 Obtaining access to file system entry points

There are several ways in which a file system entry point can be obtained. Not all user agents may in fact implement all of them. However, in order to avoid blocking UI actions while waiting on filesystem IO, we define only an asynchronous interface for Window, and restrict the synchronous API to the Worker context defined in [WEBWORKERS].

3.4.1 Using LocalFileSystem

Window implements LocalFileSystem;

All instances of the Window type are defined to also implement the LocalFileSystem interface.

WorkerGlobalScope implements LocalFileSystem;

All instances of the WorkerGlobalScope type are defined to also implement the LocalFileSystem interface.

[Supplemental, NoInterfaceObject]
interface LocalFileSystem {
    const unsigned short TEMPORARY = 0;
    const unsigned short PERSISTENT = 1;
    void requestFileSystem (unsigned short type, unsigned long long size, FileSystemCallback successCallback, optional ErrorCallback errorCallback);
    void resolveLocalFileSystemURI (DOMString uri, EntryCallback successCallback, optional ErrorCallback errorCallback);
};
3.4.1.1 Methods
requestFileSystem

Requests a filesystem in which to store application data.

If successful, this function must give access to an origin-private filesystem, as defined above.

ParameterTypeNullableOptionalDescription
typeunsigned short Whether the filesystem requested should be persistent, as defined above. Use one of TEMPORARY or PERSISTENT.
sizeunsigned long long This is an indicator of how much storage space, in bytes, the application expects to need.
successCallbackFileSystemCallback The callback that is called when the user agent provides a filesystem.
errorCallbackErrorCallback A callback that is called when errors happen, or when the request to obtain the filesystem is denied.
No exceptions.
Return type: void
resolveLocalFileSystemURI

Allows the user to look up the Entry for a file or directory referred to by a local URI.

ParameterTypeNullableOptionalDescription
uriDOMString A URI referring to a local file in a filesystem accessable via this API.
successCallbackEntryCallback A callback that is called to report the Entry to which the supplied URI refers.
errorCallbackErrorCallback A callback that is called when errors happen, or when the request to obtain the Entry is denied.
No exceptions.
Return type: void
3.4.1.2 Constants
PERSISTENT of type unsigned short
Used for storage that should not be removed by the user agent without application or user permission.
TEMPORARY of type unsigned short
Used for storage with no guarantee of persistence.

3.4.2 Using LocalFileSystemSync

WorkerGlobalScope implements LocalFileSystemSync;

All instances of the WorkerGlobalScope type are defined to also implement the LocalFileSystemSync interface.

[Supplemental, NoInterfaceObject]
interface LocalFileSystemSync {
    const unsigned short TEMPORARY = 0;
    const unsigned short PERSISTENT = 1;
    FileSystemSync requestFileSystemSync (unsigned short type, unsigned long long size) raises (FileException);
    EntrySync      resolveLocalFileSystemSyncURI (DOMString uri) raises (FileException);
};
3.4.2.1 Methods
requestFileSystemSync

Requests a filesystem in which to store application data.

If successful, this function must give access to an origin-private filesystem, as defined above.

ParameterTypeNullableOptionalDescription
typeunsigned short Whether the filesystem requested should be persistent, as defined above. Use one of TEMPORARY or PERSISTENT.
sizeunsigned long long This is an indicator of how much storage space, in bytes, the application expects to need.
ExceptionDescription
FileException
SECURITY_ERRThe application does not have permission to access the filesystem interface.
Return type: FileSystemSync
resolveLocalFileSystemSyncURI

Allows the user to look up the Entry for a file or directory referred to by a local URI.

ParameterTypeNullableOptionalDescription
uriDOMString A URI referring to a local file in a filesystem accessable via this API.
ExceptionDescription
FileException
ENCODING_ERRThe URL was invalid.
NOT_FOUND_ERRThe URL was structurally correct, but refers to a resource that does not exist.
SECURITY_ERRThe application does not have permission to access the filesystem interface or the element referred to by the URI.
Return type: EntrySync
3.4.2.2 Constants
PERSISTENT of type unsigned short
Used for storage that should not be removed by the user agent without application or user permission.
TEMPORARY of type unsigned short
Used for storage with no guarantee of persistence.

4. Shared data types

4.1 The Metadata interface

This interface supplies information about the state of a file or directory.

[NoInterfaceObject]
interface Metadata {
    readonly attribute Date modificationTime;
};

4.1.1 Attributes

modificationTime of type Date, readonly
This is the time at which the file or directory was last modified.
No exceptions.

4.2 The Flags interface

This interface is used to supply arguments to methods that look up or create files or directories.

[NoInterfaceObject]
interface Flags {
    attribute boolean create;
    attribute boolean exclusive;
};

4.2.1 Attributes

create of type boolean
Used to indicate that the user wants to create a file or directory if it was not previously there.
No exceptions.
exclusive of type boolean
By itself, exclusive must have no effect. Used with create, it causes getFile and getDirectory to fail if the target path already exists.
No exceptions.

4.2.2 Examples

This section is non-normative.

// Get the data directory, creating it if it doesn't exist.
dataDir = fsSync.root.getDirectory("data", {create: true});

// Create the lock file, if and only if it doesn't exist.
try {
  lockFile = dataDir.getFile("lockfile.txt",
                             {create: true, exclusive: true});
} catch (ex) {
  // It already exists, or something else went wrong.
  ...
}

5. The asynchronous filesystem interface

5.1 The FileSystem interface

This interface represents a file system.

[NoInterfaceObject]
interface FileSystem {
    readonly attribute DOMString      name;
    readonly attribute DirectoryEntry root;
};

5.1.1 Attributes

name of type DOMString, readonly
This is the name of the file system. The specifics of naming filesystems is unspecified, but a name must be unique across the list of exposed file systems.
No exceptions.
root of type DirectoryEntry, readonly
The root directory of the file system.
No exceptions.

5.2 The Entry interface

An abstract interface representing entries in a file system, each of which may be a File or DirectoryEntry.

[NoInterfaceObject]
interface Entry {
    readonly attribute boolean    isFile;
    readonly attribute boolean    isDirectory;
    void      getMetadata (MetadataCallback successCallback, optional ErrorCallback errorCallback);
    readonly attribute DOMString  name;
    readonly attribute DOMString  fullPath;
    readonly attribute FileSystem filesystem;
    void      moveTo (DirectoryEntry parent, optional DOMString newName, optional EntryCallback successCallback, optional ErrorCallback errorCallback);
    void      copyTo (DirectoryEntry parent, optional DOMString newName, optional EntryCallback successCallback, optional ErrorCallback errorCallback);
    DOMString toURI (optional DOMString mimeType);
    void      remove (VoidCallback successCallback, optional ErrorCallback errorCallback);
    void      getParent (EntryCallback successCallback, optional ErrorCallback errorCallback);
};

5.2.1 Attributes

filesystem of type FileSystem, readonly
The file system on which the entry resides.
No exceptions.
fullPath of type DOMString, readonly
The full absolute path from the root to the entry.
No exceptions.
isDirectory of type boolean, readonly
Entry is a directory.
No exceptions.
isFile of type boolean, readonly
Entry is a file.
No exceptions.
name of type DOMString, readonly
The name of the entry, excluding the path leading to it.
No exceptions.

5.2.2 Methods

copyTo

Copy an entry to a different location on the file system. It is an error to try to copy an entry inside itself at any depth if it is a directory, or to copy it into its parent if a name different from its current one isn't provided. Directory copies are always recursive--that is, they copy all contents of the directory.

ParameterTypeNullableOptionalDescription
parentDirectoryEntry The directory to which to move the entry.
newNameDOMString The new name of the entry. Defaults to the Entry's current name if unspecified.
successCallbackEntryCallback A callback that is called with the Entry for the new object.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void
getMetadata

Look up metadata about this entry.

ParameterTypeNullableOptionalDescription
successCallbackMetadataCallback A callback that is called with the time of the last modification.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void
getParent
Look up the parent DirectoryEntry containing this Entry. If this Entry is the root of its filesystem, its parent is itself.
ParameterTypeNullableOptionalDescription
successCallbackEntryCallback A callback that is called to return the parent Entry.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void
moveTo

Move an entry to a different location on the file system. It is an error to try to:

  • move a directory inside itself or to any child at any depth;
  • move an entry into its parent if a name different from its current one isn't provided;
  • move a file to a path occupied by a directory;
  • move a directory to a path occupied by a file;
  • move any element to a path occupied by a directory which is not empty.
A move of a file on top of an existing file must attempt to delete and replace that file. A move of a directory on top of an existing empty directory must attempt to delete and replace that directory.
ParameterTypeNullableOptionalDescription
parentDirectoryEntry The directory to which to move the entry.
newNameDOMString The new name of the entry. Defaults to the Entry's current name if unspecified.
successCallbackEntryCallback A callback that is called with the Entry for the new location.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void
remove

Deletes a file or directory. It is an error to attempt to delete a directory that is not empty. It is an error to attempt to delete the root directory of a filesystem.

ParameterTypeNullableOptionalDescription
successCallbackVoidCallback A callback that is called on success.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void
toURI

Returns a URI that can be used to identify this entry. Unlike the URN defined in [FILE-API], it has no specific expiration; as it describes a location on disk, it should be valid at least as long as that location exists. Users may supply mimeType in order to simulate the optional mime-type header associated with HTTP downloads.

Do we want to spec out the URI format/scheme? It would be quite nice if these could be edited and manipulated easily, as with normal filesystem paths.

ParameterTypeNullableOptionalDescription
mimeTypeDOMString For a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
No exceptions.
Return type: DOMString

5.3 The DirectoryEntry interface

This interface represents a directory on a file system.

[NoInterfaceObject]
interface DirectoryEntry : Entry {
    DirectoryReader createReader ();
    void            getFile (DOMString path, optional Flags options, optional EntryCallback successCallback, optional ErrorCallback errorCallback);
    void            getDirectory (DOMString path, optional Flags options, optional EntryCallback successCallback, optional ErrorCallback errorCallback);
    void            removeRecursively (VoidCallback successCallback, optional ErrorCallback errorCallback);
};

5.3.1 Methods

createReader

Creates a new DirectoryReader to read Entries from this Directory.

No parameters.
No exceptions.
Return type: DirectoryReader
getDirectory

Creates or looks up a directory.

ParameterTypeNullableOptionalDescription
pathDOMString Either an absolute path or a relative path from this DirectoryEntry to the directory to be looked up or created. It is an error to attempt to create a directory whose immediate parent does not yet exist.
optionsFlags
  • If create and exclusive are both true and the path already exists, getDirectory must fail.
  • If create is true, the path doesn't exist, and no other error occurs, getDirectory must create and return a corresponding DirectoryEntry.
  • If create is not true and the path doesn't exist, getDirectory must fail.
  • If create is not true and the path exists, but is a file, getDirectory must fail.
  • Otherwise, if no other error occurs, getDirectory must return a DirectoryEntry corresponding to path.
successCallbackEntryCallback A callback that is called to return the DirectoryEntry selected or created.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void
getFile

Creates or looks up a file.

ParameterTypeNullableOptionalDescription
pathDOMString Either an absolute path or a relative path from this DirectoryEntry to the file to be looked up or created. It is an error to attempt to create a file whose immediate parent does not yet exist.
optionsFlags
  • If create and exclusive are both true, and the path already exists, getFile must fail.
  • If create is true, the path doesn't exist, and no other error occurs, getFile must create it as a zero-length file and return a corresponding FileEntry.
  • If create is not true and the path doesn't exist, getFile must fail.
  • If create is not true and the path exists, but is a directory, getFile must fail.
  • Otherwise, if no other error occurs, getFile must return a FileEntry corresponding to path.
successCallbackEntryCallback A callback that is called to return the File selected or created.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void
removeRecursively

Deletes a directory and all of its contents, if any. In the event of an error [e.g. trying to delete a directory that contains a file that cannot be removed], some of the contents of the directory may be deleted. It is an error to attempt to delete the root directory of a filesystem.

ParameterTypeNullableOptionalDescription
successCallbackVoidCallback A callback that is called on success.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void

5.4 The DirectoryReader interface

This interface lets a user list files and directories in a directory. If there are no additions to or deletions from a directory between the first and last call to readEntries, and no errors occur, then:

[NoInterfaceObject]
interface DirectoryReader {
    void readEntries (EntriesCallback successCallback, optional ErrorCallback errorCallback);
};

5.4.1 Methods

readEntries

Read the next block of entries from this directory.

ParameterTypeNullableOptionalDescription
successCallbackEntriesCallback Called once per successful call to readEntries to deliver the next previously-unreported set of Entries in the associated Directory. If all Entries have already been returned from previous invocations of readEntries, successCallback must be called with a zero-length array as an argument.
errorCallbackErrorCallback A callback indicating that there was an error reading from the Directory.
No exceptions.
Return type: void

5.5 The FileEntry interface

This interface represents a file on a file system.

[NoInterfaceObject]
interface FileEntry : Entry {
    void createWriter (FileWriterCallback successCallback, optional ErrorCallback errorCallback);
    void file (FileCallback successCallback, optional ErrorCallback errorCallback);
};

5.5.1 Methods

createWriter

Creates a new FileWriter associated with the file that this FileEntry represents.

ParameterTypeNullableOptionalDescription
successCallbackFileWriterCallback A callback that is called with the new FileWriter.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void
file

Returns a File that represents the current state of the file that this FileEntry represents.

ParameterTypeNullableOptionalDescription
successCallbackFileCallback A callback that is called with the new FileWriter.
errorCallbackErrorCallback A callback that is called when errors happen.
No exceptions.
Return type: void

5.6 Callbacks

Several calls in this API are asynchronous, and use callbacks.

5.6.1 The FileSystemCallback interface

When requestFileSystem() succeeds, the following callback is made:

[NoInterfaceObject, Callback=FunctionOnly]
interface FileSystemCallback {
    void handleEvent (FileSystem filesystem);
};
5.6.1.1 Methods
handleEvent

The file system was successfully obtained.

ParameterTypeNullableOptionalDescription
filesystemFileSystem The file systems to which the app is granted access.
No exceptions.
Return type: void

5.6.2 The EntryCallback interface

This interface is the callback used to look up Entry objects.

[NoInterfaceObject, Callback=FunctionOnly]
interface EntryCallback {
    void handleEvent (Entry entry);
};
5.6.2.1 Methods
handleEvent
Used to supply an Entry as a response to a user query.
ParameterTypeNullableOptionalDescription
entryEntry
No exceptions.
Return type: void

5.6.3 The EntriesCallback interface

When readEntries() succeeds, the following callback is made.

[NoInterfaceObject, Callback=FunctionOnly]
interface EntriesCallback {
    void handleEvent (Entry[] entries);
};
5.6.3.1 Methods
handleEvent
Used to supply an array of Entries as a response to a user query.
ParameterTypeNullableOptionalDescription
entriesEntry[]
No exceptions.
Return type: void

5.6.4 The MetadataCallback interface

This interface is the callback used to look up file and directory metadata.

[NoInterfaceObject, Callback=FunctionOnly]
interface MetadataCallback {
    void handleEvent (Metadata metadata);
};
5.6.4.1 Methods
handleEvent

Used to supply file or directory metadata as a response to a user query.

ParameterTypeNullableOptionalDescription
metadataMetadata
No exceptions.
Return type: void

5.6.5 The FileWriterCallback interface

This interface is the callback used to create a FileWriter.

[NoInterfaceObject, Callback=FunctionOnly]
interface FileWriterCallback {
    void handleEvent (FileWriter fileWriter);
};
5.6.5.1 Methods
handleEvent

Used to supply a FileWriter as a response to a user query.

ParameterTypeNullableOptionalDescription
fileWriterFileWriter
No exceptions.
Return type: void

5.6.6 The FileCallback interface

This interface is the callback used to obtain a File.

[NoInterfaceObject, Callback=FunctionOnly]
interface FileCallback {
    void handleEvent (File file);
};
5.6.6.1 Methods
handleEvent

Used to supply a File as a response to a user query.

ParameterTypeNullableOptionalDescription
fileFile
No exceptions.
Return type: void

5.6.7 The VoidCallback interface

This interface is the generic callback used to indicate success of an asynchronous method.

[NoInterfaceObject, Callback=FunctionOnly]
interface VoidCallback {
    void handleEvent ();
};
5.6.7.1 Methods
handleEvent
No parameters.
No exceptions.
Return type: void

5.6.8 The ErrorCallback interface

When an error occurs, the following callback is made:

[NoInterfaceObject, Callback=FunctionOnly]
interface ErrorCallback {
    void handleEvent (FileError err);
};
5.6.8.1 Methods
handleEvent

There was an error with the request. Details are provided by the FileError parameter.

ParameterTypeNullableOptionalDescription
errFileError The error that was generated.
No exceptions.
Return type: void

6. The synchronous filesystem interface

6.1 The FileSystemSync interface

This interface represents a file system.

[NoInterfaceObject]
interface FileSystemSync {
    readonly attribute DOMString          name;
    readonly attribute DirectoryEntrySync root;
};

6.1.1 Attributes

name of type DOMString, readonly
This is the name of the file system. The specifics of naming filesystems is unspecified, but a name must be unique across the list of exposed file systems.
No exceptions.
root of type DirectoryEntrySync, readonly
The root directory of the file system.
No exceptions.

6.2 The EntrySync interface

An abstract interface representing entries in a file system, each of which may be a FileEntrySync or DirectoryEntrySync.

Some have requested support for archive files. I've not required that, but I've left space for it by not ruling out having both isFile and isDirectory be true. I welcome comments on this approach.
[NoInterfaceObject]
interface EntrySync {
    readonly attribute boolean        isFile;
    readonly attribute boolean        isDirectory;
    Metadata           getMetadata () raises (FileException);
    readonly attribute DOMString      name;
    readonly attribute DOMString      fullPath;
    readonly attribute FileSystemSync filesystem;
    EntrySync          moveTo (DirectoryEntrySync parent, optional DOMString newName) raises (FileException);
    EntrySync          copyTo (DirectoryEntrySync parent, optional DOMString newName) raises (FileException);
    DOMString          toURI (optional DOMString mimeType);
    void               remove () raises (FileException);
    DirectoryEntrySync getParent ();
};

6.2.1 Attributes

filesystem of type FileSystemSync, readonly
The file system on which the entry resides.
No exceptions.
fullPath of type DOMString, readonly
The full absolute path from the root to the entry.
No exceptions.
isDirectory of type boolean, readonly
EntrySync is a directory.
No exceptions.
isFile of type boolean, readonly
EntrySync is a file.
No exceptions.
name of type DOMString, readonly
The name of the entry, excluding the path leading to it.
No exceptions.

6.2.2 Methods

copyTo

Copy an entry to a different location on the file system. It is an error to try to copy an entry inside itself at any depth if it is a directory, or to copy it into its parent if a name different from its current one isn't provided.

ParameterTypeNullableOptionalDescription
parentDirectoryEntrySync The directory to which to move the entry.
newNameDOMString The new name of the entry. Defaults to the EntrySync's current name if unspecified.
ExceptionDescription
FileException
ENCODING_ERRThe name supplied was invalid.
NOT_FOUND_ERRThe target directory does not exist.
INVALID_MODIFICATION_ERRThe user attempted to copy an entry into its parent without changing its name, or attempted to copy a directory into a directory that it contains directly or indirectly.
NO_MODIFICATION_ALLOWED_ERRThe target directory is not writable.
QUOTA_EXCEEDED_ERRThe operation would cause the application to exceed its storage quota.
SECURITY_ERRThe user agent determined that it was not safe to carry out this action.
Return type: EntrySync
getMetadata

Look up metadata about this entry.

No parameters.
ExceptionDescription
FileException
NOT_FOUND_ERRThe entry no longer exists.
INVALID_STATE_ERRThis FileSystemSync is no longer valid for some reason other than it having been deleted.
SECURITY_ERRThe user agent determined that it was not safe to carry out this action.
Return type: Metadata
getParent
Look up the parent DirectoryEntrySync containing this Entry. If this EntrySync is the root of its filesystem, its parent is itself.
No parameters.
No exceptions.
Return type: DirectoryEntrySync
moveTo

Move an entry to a different location on the file system. It is an error to try to:

  • move a directory inside itself or to any child at any depth;
  • move an entry into its parent if a name different from its current one isn't provided;
  • move a file to a path occupied by a directory;
  • move a directory to a path occupied by a file;
  • move any element to a path occupied by a directory which is not empty.
A move of a file on top of an existing file must attempt to delete and replace that file. A move of a directory on top of an existing empty directory must attempt to delete and replace that directory.
ParameterTypeNullableOptionalDescription
parentDirectoryEntrySync The directory to which to move the entry.
newNameDOMString The new name of the entry. Defaults to the EntrySync's current name if unspecified.
ExceptionDescription
FileException
ENCODING_ERRThe name supplied was invalid.
NOT_FOUND_ERRThe target directory does not exist.
INVALID_MODIFICATION_ERRThe user attempted to move an entry into its parent without changing its name, or attempted to move a directory into a directory that it contains directly or indirectly.
NO_MODIFICATION_ALLOWED_ERRThe either the source entry, its parent directory, or the target directory is not writable.
SECURITY_ERRThe user agent determined that it was not safe to carry out this action.
Return type: EntrySync
remove

Deletes a file or directory. It is an error to attempt to delete a directory that is not empty. It is an error to attempt to delete the root directory of a filesystem.

No parameters.
ExceptionDescription
FileException
NOT_FOUND_ERRThe target directory does not exist.
INVALID_MODIFICATION_ERRThe user attempted to remove a directory that was not empty.
NO_MODIFICATION_ALLOWED_ERRThe target or its containing directory is not writable.
SECURITY_ERRThe user agent determined that it was not safe to carry out this action.
Return type: void
toURI

Returns a URI that can be used to identify this entry. Unlike the URN defined in [FILE-API], it has no specific expiration; as it describes a location on disk, it should be valid at least as long as that location exists. Users may supply mimeType in order to simulate the optional mime-type header associated with HTTP downloads.

If we use the same opaque URI scheme as in [FILE-API], users won't be able to edit and generate URIs themselves. On the other hand, it would prevent us from having to go to all the trouble of designing a new scheme, and it would simplify the use of the two APIs together.

ParameterTypeNullableOptionalDescription
mimeTypeDOMString For a FileEntry, the mime type to be used to interpret the file, when loaded through this URI.
No exceptions.
Return type: DOMString

6.3 The DirectoryEntrySync interface

This interface represents a directory on a file system.

[NoInterfaceObject]
interface DirectoryEntrySync : EntrySync {
    DirectoryReaderSync createReader () raises (FileException);
    FileEntrySync       getFile (DOMString path, optional Flags options) raises (FileException);
    DirectoryEntrySync  getDirectory (DOMString path, optional Flags options) raises (FileException);
    void                removeRecursively () raises (FileException);
};

6.3.1 Methods

createReader

Creates a new DirectoryReaderSync to read EntrySyncs from this DirectorySync.

No parameters.
ExceptionDescription
FileException
NOT_FOUND_ERRThe directory no longer exists.
SECURITY_ERRThe user agent determined that it was not safe to carry out this action.
Return type: DirectoryReaderSync
getDirectory

Creates or looks up a directory.

ParameterTypeNullableOptionalDescription
pathDOMString Either an absolute path or a relative path from this DirectoryEntrySync to the directory to be looked up or created. It is an error to attempt to create a directory whose immediate parent does not yet exist.
optionsFlags
  • If create and exclusive are both true and the path already exists, getDirectory must fail.
  • If create is true, the path doesn't exist, and no other error occurs, getDirectory must create and return a corresponding DirectoryEntry.
  • If create is not true and the path doesn't exist, getDirectory must fail.
  • If create is not true and the path exists, but is a file, getDirectory must fail.
  • Otherwise, if no other error occurs, getDirectory must return a DirectoryEntrySync corresponding to path.
ExceptionDescription
FileException
ENCODING_ERRThe path was invalid.
NOT_FOUND_ERRThe path was structurally correct, but refers to a resource that does not exist.
NO_MODIFICATION_ALLOWED_ERRThe target directory is not writable.
PATH_EXISTS_ERRThe user attempted to create a directory where an element already exists.
QUOTA_EXCEEDED_ERRThe operation would cause the application to exceed its storage quota.
SECURITY_ERRThe application does not have permission to access the element referred to by path.
TYPE_MISMATCH_ERRThe path supplied exists, but is not a directory.
Return type: DirectoryEntrySync
getFile

Creates or looks up a file.

ParameterTypeNullableOptionalDescription
pathDOMString Either an absolute path or a relative path from this DirectoryEntrySync to the file to be looked up or created. It is an error to attempt to create a file whose immediate parent does not yet exist.
optionsFlags
  • If create and exclusive are both true and the path already exists, getFile must fail.
  • If create is true, the path doesn't exist, and no other error occurs, getFile must create it as a zero-length file and return a corresponding FileEntry.
  • If create is not true and the path doesn't exist, getFile must fail.
  • If create is not true and the path exists, but is a directory, getFile must fail.
  • Otherwise, if no other error occurs, getFile must return a FileEntrySync corresponding to path.
ExceptionDescription
FileException
ENCODING_ERRThe path was invalid.
NOT_FOUND_ERRThe path was structurally correct, but refers to a resource that does not exist.
NO_MODIFICATION_ALLOWED_ERRThe target directory or file is not writable.
PATH_EXISTS_ERRThe user attempted to create a file where an element already exists.
QUOTA_EXCEEDED_ERRThe operation would cause the application to exceed its storage quota.
SECURITY_ERRThe application does not have permission to access the element referred to by path.
TYPE_MISMATCH_ERRThe path supplied exists, but is not a directory.
Return type: FileEntrySync
removeRecursively

Deletes a directory and all of its contents, if any. In the event of an error [e.g. trying to delete a directory that contains a file that cannot be removed], some of the contents of the directory may be deleted. It is an error to attempt to delete the root directory of a filesystem.

No parameters.
ExceptionDescription
FileException
NOT_FOUND_ERRThis DirectoryEntrySync refers to a resource that does not exist.
INVALID_STATE_ERRThis DirectoryEntrySync is no longer valid for some reason other than it having been deleted.
NO_MODIFICATION_ALLOWED_ERRAt least one of the target directory, its parent, or some of its contents, is not writable.
SECURITY_ERRThe application does not have permission to access the target directory, its parent, or some of its contents.
Return type: void

6.4 The DirectoryReaderSync interface

This interface lets a user list files and directories in a directory. If there are no additions to or deletions from a directory between the first and last call to readEntries, and no errors occur, then:

[NoInterfaceObject]
interface DirectoryReaderSync {
    EntrySync[] readEntries () raises (FileException);
};

6.4.1 Methods

readEntries

Read the next block of entries from this directory.

No parameters.
ExceptionDescription
FileException
NOT_FOUND_ERRThe directory no longer exists.
INVALID_STATE_ERRThe directory has been modified since the first call to readEntries began to be processed.
SECURITY_ERRThe user agent determined that it was not safe to carry out this action.
Return type: EntrySync[]

6.5 The FileEntrySync interface

This interface represents a file on a file system.

[NoInterfaceObject]
interface FileEntrySync : EntrySync {
    FileWriterSync createWriter ();
    File           file () raises (FileException);
};

6.5.1 Methods

createWriter

Creates a new FileWriterSync associated with the file that this FileEntrySync represents.

No parameters.
No exceptions.
Return type: FileWriterSync
file

Returns a File that represents the current state of the file that this FileEntrySync represents.

No parameters.
ExceptionDescription
FileException
NOT_FOUND_ERRThe entry no longer exists.
INVALID_STATE_ERRThis FileEntrySync is no longer valid for some reason other than it having been deleted.
SECURITY_ERRThe user agent determined that it was not safe to carry out this action.
Return type: File

7. Dealing with errors and exceptions

7.1 The FileError interface

This interface extends the FileError interface described in [FILE-WRITER] to add several new error codes. It is used to report errors asynchronously.

interface FileError {
    const unsigned short NOT_FOUND_ERR = 1;
    const unsigned short SECURITY_ERR = 2;
    const unsigned short ABORT_ERR = 3;
    const unsigned short NOT_READABLE_ERR = 4;
    const unsigned short ENCODING_ERR = 5;
    const unsigned short NO_MODIFICATION_ALLOWED_ERR = 6;
    const unsigned short INVALID_STATE_ERR = 7;
    const unsigned short SYNTAX_ERR = 8;
    const unsigned short INVALID_MODIFICATION_ERR = 9;
    const unsigned short QUOTA_EXCEEDED_ERR = 10;
    const unsigned short TYPE_MISMATCH_ERR = 11;
    const unsigned short PATH_EXISTS_ERR = 12;
    attribute unsigned short code;
};

7.1.1 Attributes

code of type unsigned short
The code attribute, on getting, must return one of the constants of the FileError error, which must be the most appropriate code from the table below.
No exceptions.

7.1.2 Constants

ABORT_ERR of type unsigned short
ENCODING_ERR of type unsigned short
INVALID_MODIFICATION_ERR of type unsigned short
INVALID_STATE_ERR of type unsigned short
NOT_FOUND_ERR of type unsigned short
NOT_READABLE_ERR of type unsigned short
NO_MODIFICATION_ALLOWED_ERR of type unsigned short
PATH_EXISTS_ERR of type unsigned short
QUOTA_EXCEEDED_ERR of type unsigned short
SECURITY_ERR of type unsigned short
SYNTAX_ERR of type unsigned short
TYPE_MISMATCH_ERR of type unsigned short

7.2 The FileException exception

This interface extends the FileException interface described in [FILE-WRITER] to add several new error codes. Any errors that need to be reported synchronously, including all that occur during use of the synchronous filesystem methods, are reported using the FileException exception.
exception FileException {
    const unsigned short NOT_FOUND_ERR = 1;
    const unsigned short SECURITY_ERR = 2;
    const unsigned short ABORT_ERR = 3;
    const unsigned short NOT_READABLE_ERR = 4;
    const unsigned short ENCODING_ERR = 5;
    const unsigned short NO_MODIFICATION_ALLOWED_ERR = 6;
    const unsigned short INVALID_STATE_ERR = 7;
    const unsigned short SYNTAX_ERR = 8;
    const unsigned short INVALID_MODIFICATION_ERR = 9;
    const unsigned short QUOTA_EXCEEDED_ERR = 10;
    const unsigned short TYPE_MISMATCH_ERR = 11;
    const unsigned short PATH_EXISTS_ERR = 12;
    readonly attribute unsigned short code;
};

7.2.1 Fields

code of type readonly attribute unsigned short
The code attribute, on getting, must return one of the constants of the FileError error, which must be the most appropriate code from the table below.

7.2.2 Constants

ABORT_ERR of type unsigned short
ENCODING_ERR of type unsigned short
INVALID_MODIFICATION_ERR of type unsigned short
INVALID_STATE_ERR of type unsigned short
NOT_FOUND_ERR of type unsigned short
NOT_READABLE_ERR of type unsigned short
NO_MODIFICATION_ALLOWED_ERR of type unsigned short
PATH_EXISTS_ERR of type unsigned short
QUOTA_EXCEEDED_ERR of type unsigned short
SECURITY_ERR of type unsigned short
SYNTAX_ERR of type unsigned short
TYPE_MISMATCH_ERR of type unsigned short

7.3 Error Code Descriptions

NameValueDescription
NO_MODIFICATION_ALLOWED_ERR7 user agent must use this code when attempting to write to a file or directory which cannot be modified due to the state of the underlying filesystem.
NOT_FOUND_ERR8 user agent must use this code if a required file or directory could not be found at the time an operation was processed.
INVALID_STATE_ERR11 user agent may use this code if an operation depends on state cached in an interface object that has changed since it was read from disk.
Which values will actually go stale? Modification time, name, more rarely type. If an atomic save [replacing a file with a new one of the same name] happens underneath, should we even be required to notice?
INVALID_MODIFICATION_ERR13 user agent may use this code if the modification requested is illegal. Examples of invalid modifications include moving a directory into its own child or moving a file into its parent directory without changing its name.
SECURITY_ERR18 user agent may use this code if:
  • it is determined that certain files are unsafe for access within a Web application
  • it is determined that too many calls are being made on file resources
This is a security error code to be used in situations not covered by any other error codes.
ABORT_ERR20 This value must not be used in this API.
QUOTA_EXCEEDED_ERR22 user agent must use this code if the operation failed because it would cause the application to exceed its storage quota.
NOT_READABLE_ERR24 user agent must use this code if a file or directory cannot be read, typically due due to permission problems that occur after a reference to a file has been acquired (e.g. concurrent lock with another application).
ENCODING_ERR26 user agent must use this code when a URI supplied to the API is malformed.

8. Uniformity of interface

In order to make it easy for web app developers to write portable applications that work on all platforms, we enforce certain restrictions and make certain guarantees with respect to paths used in this API.

This section is non-normative.

These restrictions are intended to prevent developers from accidentally requiring the creation of paths that can only be created on a subset of platforms. They are not intended to prevent access to files created outside of this API.

The implementation must refuse to create any file or directory whose name or existence would violate these rules. The implementation may accept a noncompliant path where it is used to look up an Entry or EntrySync for an existing file or directory. The implementation must not accept a noncompliant path where it designates the new name of a file or directory to be moved, copied, or created.

What about path and path segment lengths? For portability we should probably clip segments at 255 bytes of UTF-8 in normalization form D, and clip paths at 4095 bytes, but users can't easily check the byte length of strings, or renormalize, so that makes for an annoying API. It's also hard to control the true length of a path, due to renames of parent directories, so we really just want to reject the obviously-too-long; they won't often really come up anyway.

What about normalization? Are two different normalizations of the same string equivalent as filenames? We don't want to let any underlying platform behaviors leak through. This could be solved for in-API paths by supplying a "filenames are equal" function and normalizing everything inside the API, but we'd have to do it in both directions, since paths created outside the API might not be normalized.

8.1 Case-sensitivity

Paths in this filesystem are case-insensitive and case-preserving, regardless of the rules of the underlying filesystem, if any.

Case-insensitivity should respect the locale of the user.

We could choose the user or the author; I think the user's probably the better way to go. There are still situations in which you can get into trouble, but matching the locale of the user's computer should avoid many of the most common conflicts.

8.2 Directories

The directory separator is '/', regardless of the directory separator used by the underlying system, if any.

The character '/', when it is the first character in a path, refers to the root directory.

All absolute paths begin with '/'; no relative paths begin with '/'.

A relative path describes how to get from a particular directory to a file or directory. All methods that accept paths are on DirectoryEntry or DirectoryEntrySync objects; the paths, if relative, are interpreted as being relative to the directories represented by these objects.

An absolute path is a relative path from the root directory, prepended with a '/'.

'.', when used where it is legal to use a directory name, refers to the currently-referenced directory. Thus 'foo/./bar' is equivalent to 'foo/bar', and './foo' is equivalent to 'foo'.

'..', when used where it is legal to use a directory name, refers to the parent of the currently-referenced directory. Thus, 'foo/..' refers to the directory containing 'foo', and '../foo' refers to an element named 'foo' in the parent of the directory on whose DirectoryEntry or DirectoryEntrySync the method receiving the path is being called.

Directories must not be made to contain more than 5000 entries.

8.3 Naming restrictions

Files and directories must not be named any of the following, and must not begin with any of the following followed by a period.

These restrictions hold regardless of case, i.e. "con", "PrN" are also illegal.

File and directory names must not end in period or whitespace.

File and directory names must not contain any of the following characters:

File and directory names must not contain any character whose representation in UTF-8 is between 0 and 31, inclusive.

A. Acknowledgements

Thanks to Arun Ranganathan for his File API, Opera for theirs, and Robin Berjon both for his work on various file APIs and for ReSpec.

B. References

B.1 Normative references

[FILE-API]
Arun Ranganathan. File API. 17 November 2009. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2009/WD-FileAPI-20091117/
[FILE-WRITER]
Eric Uhrhane. File Writer API. W3C Working Draft. (Work in progress.) URL: http://dev.w3.org/2009/dap/file-system/file-writer.html
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
[WEBWORKERS]
Ian Hickson. Web Workers. 22 December 2009. W3C Working Draft. (Work in progress.) URL: http://www.w3.org/TR/2009/WD-workers-20091222/

B.2 Informative references

No informative references.