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.

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

Introduction

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.

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 URLs 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 URL 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.

Examples

          // In the DOM or worker context:

          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);
            });
          }
          requestFileSystem(TEMPORARY, 1024 * 1024, function(fs) {
            useAsyncFS(fs);
          });

          // In a worker:

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

Terminology

The term throw in this specification, as it pertains to exceptions, is used as defined in the DOM4 specification [[!DOM4]].

DOMError is defined in the DOM4 specification [[!DOM4]].

File is defined in the File API specification [[!FILE-API]].

FileWriter and FileWriterSync are defined in the FileWriter specification [[!FILE-WRITER]].

Data Persistence and accessing the API

Temporary vs. Persistent Storage

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].

Restrictions

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

Security Considerations

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.

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]].

Using LocalFileSystem

const unsigned short TEMPORARY = 0
Used for storage with no guarantee of persistence.
const unsigned short PERSISTENT = 1
Used for storage that should not be removed by the user agent without application or user permission.
void 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.

unsigned short type
Whether the filesystem requested should be persistent, as defined above. Use one of TEMPORARY or PERSISTENT.
unsigned long long size
This is an indicator of how much storage space, in bytes, the application expects to need.
FileSystemCallback successCallback
The callback that is called when the user agent provides a filesystem.
optional ErrorCallback errorCallback
A callback that is called when errors happen, or when the request to obtain the filesystem is denied.
void resolveLocalFileSystemURL ()

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

DOMString url
A URL referring to a local file in a filesystem accessable via this API.
EntryCallback successCallback
A callback that is called to report the Entry to which the supplied URL refers.
optional ErrorCallback errorCallback
A callback that is called when errors happen, or when the request to obtain the Entry is denied.

Using LocalFileSystemSync

const unsigned short TEMPORARY = 0
Used for storage with no guarantee of persistence.
const unsigned short PERSISTENT = 1
Used for storage that should not be removed by the user agent without application or user permission.
FileSystemSync 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.

unsigned short type
Whether the filesystem requested should be persistent, as defined above. Use one of TEMPORARY or PERSISTENT.
unsigned long long size
This is an indicator of how much storage space, in bytes, the application expects to need.
EntrySync resolveLocalFileSystemSyncURL ()

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

DOMString url
A URL referring to a local file in a filesystem accessable via this API.

Shared data types

The Metadata interface

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

readonly attribute Date modificationTime
This is the time at which the file or directory was last modified.
readonly attribute unsigned long long size
The size of the file, in bytes. This MUST return 0 for directories.

The Flags dictionary

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

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

Examples

            // 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.
              ...
            }
          

The asynchronous filesystem interface

The FileSystem interface

This interface represents a file system.

readonly attribute DOMString name
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.
readonly attribute DirectoryEntry root
The root directory of the file system.

The Entry interface

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

readonly attribute boolean isFile
Entry is a file.
readonly attribute boolean isDirectory
Entry is a directory.
void getMetadata ()

Look up metadata about this entry.

MetadataCallback successCallback
A callback that is called with the time of the last modification.
optional ErrorCallback errorCallback
A callback that is called when errors happen.
readonly attribute DOMString name
The name of the entry, excluding the path leading to it.
readonly attribute DOMString fullPath
The full absolute path from the root to the entry.
readonly attribute FileSystem filesystem
The file system on which the entry resides.
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.

DirectoryEntry parent
The directory to which to move the entry.
optional DOMString newName
The new name of the entry. Defaults to the Entry's current name if unspecified.
EntryCallback successCallback
A callback that is called with the Entry for the new location.
optional ErrorCallback errorCallback
A callback that is called when errors happen.
void copyTo (DirectoryEntry parent, DOMString newName)

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

  • copy a directory inside itself or to any child at any depth;
  • copy an entry into its parent if a name different from its current one isn't provided;
  • copy a file to a path occupied by a directory;
  • copy a directory to a path occupied by a file;
  • copy any element to a path occupied by a directory which is not empty.
A copy of a file on top of an existing file MUST attempt to delete and replace that file.
A copy of a directory on top of an existing empty directory MUST attempt to delete and replace that directory.
Directory copies are always recursive--that is, they copy all contents of the directory.

DirectoryEntry parent
The directory to which to move the entry.
optional DOMString newName
The new name of the entry. Defaults to the Entry's current name if unspecified.
EntryCallback successCallback
A callback that is called with the Entry for the new object.
optional ErrorCallback errorCallback
A callback that is called when errors happen.
DOMString toURL ()

Returns a URL 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.

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

How and where can these URLs be used? Can they be interchangeable with online URLs for the same domain?

Proposal currently under discussion:

  • Use a format such as filesystem:http://example.domain/persistent-or-temporary/path/to/file.html.
  • URLs should be usable for anything that online URLs can be used for, whether they appear in online or filesystem-resident web pages.
  • However, they can only be used by the origin that owns the filesystem. No other origin can e.g. reference another origin's filesystem in an IMG tag.

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.

VoidCallback successCallback
A callback that is called on success.
optional ErrorCallback errorCallback
A callback that is called when errors happen.
void getParent ()
Look up the parent DirectoryEntry containing this Entry. If this Entry is the root of its filesystem, its parent is itself.
EntryCallback successCallback
A callback that is called to return the parent Entry.
optional ErrorCallback errorCallback
A callback that is called when errors happen.

The DirectoryEntry interface

This interface represents a directory on a file system.

DirectoryReader createReader ()

Creates a new DirectoryReader to read Entries from this Directory.

void getFile ()

Creates or looks up a file.

DOMString path
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.
optional Flags options
  • 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.
EntryCallback successCallback
A callback that is called to return the File selected or created.
optional ErrorCallback errorCallback
A callback that is called when errors happen.
void getDirectory ()

Creates or looks up a directory.

DOMString path
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.
optional Flags options
  • 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.
EntryCallback successCallback
A callback that is called to return the DirectoryEntry selected or created.
optional ErrorCallback errorCallback
A callback that is called when errors happen.
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.

VoidCallback successCallback
A callback that is called on success.
optional ErrorCallback errorCallback
A callback that is called when errors happen.

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:

void readEntries ()

Read the next block of entries from this directory.

EntriesCallback successCallback
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.
optional ErrorCallback errorCallback
A callback indicating that there was an error reading from the Directory.

The FileEntry interface

This interface represents a file on a file system.

void createWriter ()

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

FileWriterCallback successCallback
A callback that is called with the new FileWriter.
optional ErrorCallback errorCallback
A callback that is called when errors happen.
void file ()

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

FileCallback successCallback
A callback that is called with the File.
optional ErrorCallback errorCallback
A callback that is called when errors happen.

Callbacks

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

The FileSystemCallback interface

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

void handleEvent ()

The file system was successfully obtained.

FileSystem filesystem
The file systems to which the app is granted access.

The EntryCallback interface

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

void handleEvent(Entry entry)
Used to supply an Entry as a response to a user query.

The EntriesCallback interface

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

void handleEvent(Entry[] entries)
Used to supply an array of Entries as a response to a user query.

The MetadataCallback interface

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

void handleEvent (Metadata metadata)

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

The FileWriterCallback interface

This interface is the callback used to create a FileWriter.

void handleEvent (FileWriter fileWriter)

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

The FileCallback interface

This interface is the callback used to obtain a File.

void handleEvent (File file)

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

The VoidCallback interface

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

void handleEvent ()

The ErrorCallback interface

When an error occurs, the following callback is made:

void handleEvent ()

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

DOMError err
The error that was generated.

The synchronous filesystem interface

The FileSystemSync interface

This interface represents a file system.

readonly attribute DOMString name
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.
readonly attribute DirectoryEntrySync root
The root directory of the file system.

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.

readonly attribute boolean isFile
EntrySync is a file.
readonly attribute boolean isDirectory
EntrySync is a directory.
Metadata getMetadata ()

Look up metadata about this entry.

readonly attribute DOMString name
The name of the entry, excluding the path leading to it.
readonly attribute DOMString fullPath
The full absolute path from the root to the entry.
readonly attribute FileSystemSync filesystem
The file system on which the entry resides.
EntrySync 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.

DirectoryEntrySync parent
The directory to which to move the entry.
optional DOMString newName
The new name of the entry. Defaults to the EntrySync's current name if unspecified.
EntrySync copyTo (DirectoryEntrySync parent, DOMString newName)

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

  • copy a directory inside itself or to any child at any depth;
  • copy an entry into its parent if a name different from its current one isn't provided;
  • copy a file to a path occupied by a directory;
  • copy a directory to a path occupied by a file;
  • copy any element to a path occupied by a directory which is not empty.
A copy of a file on top of an existing file MUST attempt to delete and replace that file.
A copy of a directory on top of an existing empty directory MUST attempt to delete and replace that directory.
Directory copies are always recursive--that is, they copy all contents of the directory.

DirectoryEntrySync parent
The directory to which to move the entry.
optional DOMString newName
The new name of the entry. Defaults to the EntrySync's current name if unspecified.
DOMString toURL ()

Returns a URL 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.

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.

DirectoryEntrySync getParent ()
Look up the parent DirectoryEntrySync containing this Entry. If this EntrySync is the root of its filesystem, its parent is itself.

The DirectoryEntrySync interface

This interface represents a directory on a file system.

DirectoryReaderSync createReader ()

Creates a new DirectoryReaderSync to read EntrySyncs from this DirectorySync.

FileEntrySync getFile ()

Creates or looks up a file.

DOMString path
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.
optional Flags options
  • 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.
DirectoryEntrySync getDirectory ()

Creates or looks up a directory.

DOMString path
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.
optional Flags options
  • 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.
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.

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:

EntrySync[] readEntries ()

Read the next block of entries from this directory.

The FileEntrySync interface

This interface represents a file on a file system.

FileWriterSync createWriter ()

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

File file ()

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

Errors and Exceptions

Occurrence

Error conditions can occur when attempting to write files. The list below of potential error conditions is informative, with links to normative descriptions of errors:

An operation on a file may fail due to the file [or a parent directory] having been removed before the operation is attempted. See NotFoundError.

An operation on a file may not make sense, e.g. moving a directory into one of its own children. See InvalidModificationError.

An operation on a file may not make sense if the underlying filesystem has had changes made since the reference was obtained. See TypeMismatchError, InvalidStateError.

Users may accidentally attempt to create a file where another already exists. See PathExistsError.

Definitions

Synchronous methods MUST throw an exception of the most appropriate type in the table below if there has been an error with writing.

If an error occurs while processing an asynchronous method, the err argument to the ErrorCallback MUST be a DOMError object [[!DOM4]] of the most appropriate type from the table below.

Error Descriptions

NameDescription
EncodingError A path or URL supplied to the API was malformed.
InvalidModificationError The modification requested was illegal. Examples of invalid modifications include moving a directory into its own child, moving a file into its parent directory without changing its name, or copying a directory to a path occupied by a file.
InvalidStateError An operation depended on state cached in an interface object, but that state 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?
NotFoundError A required file or directory could not be found at the time an operation was processed.
NotReadableErr A required file or directory could be read.
NoModificationAllowedError The user attempted to write to a file or directory which could not be modified due to the state of the underlying filesystem.
PathExistsError The user agent failed to create a file or directory due to the existence of a file or directory with the same path.
QuotaExceededError The operation failed because it would cause the application to exceed its storage quota.
SecurityError
  • A required file was unsafe for access within a Web application
  • Too many calls are being made on filesystem resources
This is a security error code to be used in situations not covered by any other error codes.
TypeMismatchError The user has attempted to look up a file or directory, but the Entry found is of the wrong type [e.g. is a DirectoryEntry when the user requested a FileEntry].

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.

The implementation MUST refuse to create any file or directory whose name or existence would violate these rules. 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.

Case-sensitivity

Paths in this filesystem MUST be case sensitive and case-preserving.

Encoding

Implementations MUST accept any valid UTF-8 sequence as a path segment, so long as it does not include any characters or sequences restricted below. When returning paths or path segments, implementations MUST return them in the same normalization in which they were presented.

Naming restrictions

File and directory names MUST NOT contain either of the following characters:

There's been discussion on whether backslash '\' (U+005c) should be disallowed or not. In favor of leaving it in is that it's a legal character on some filesystems, and it seems somewhat arbitrary to remove it. Opposed is that it may cause confusion, and in at least some cases complicates implementation.

Directories

The directory separator is '/' (U+002F).

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.

What about path and path segment lengths? Should we limit them at all? It's 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. We should at least provide minimum lengths for paths and segments.

Should we limit the number of elements in a directory?

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.