- From: Jan Varga <jan.varga@gmail.com>
- Date: Thu, 25 Apr 2013 18:07:07 +0200
- To: public-webapps@w3.org
- Message-ID: <CAB1sDKyGBbSSVgSQ_5GpNA_tt9r2Pvm+VNPKAZgJvRSNVuPyJQ@mail.gmail.com>
Hi WebApps! There has been a lot of controversy about implementing a file system API in other browsers. Firefox and IE already support storing files in IndexedDB, but it seems that web developers need something simpler in some cases and there's also the filesystem URL scheme that is not covered by files in IndexedDB. This new proposal is heavily based on Apple's minimal filesystem API proposal [1], on Mozilla's DeviceStorage API 2 [2] and on Mozilla's current FileHandle API [3]. It is only designed for the use case of sandboxed local file storage. In Firefox, the FileHandle API provides the ability to write to a file, as well as the locking mechanisms needed to allow writing safely. The FileHandle interface is currently supported in IndexedDB and it is also planned for DeviceStorage API. However, the new proposal for the file system API uses a modified version of the FileHandle API. The FileHandle interface acts exactly like LockedFile in the current FileHandle API. I.e. it represents an opened file and it automatically closes if you stop posting requests against it (like transactions in IDB except it doesn't provide any rollback functionality, i.e. only Isolation of the ACID). There's a documentation for the current FileHandle API [4], which contains detailed description of the LockedFile interface (that now becomes the new FileHandle interface). Here's the proposed file system API: Getting the root directory: enum PersistenceType { "temporary", "permanent" }; dictionary FilesystemParameters { PersistenceType storage; }; partial interface Navigator { Directory getSandboxedFilesystem(optional FilesystemParameters parameters); }; The Directory interface: enum FileOpenMode { "read", "write", "append" }; interface Directory { readonly attribute DOMString name; // Asynchronously returns boolean true or false to indicate success. Future<boolean> create(DOMString name, optional Blob blob); // Asynchronously returns the newly created Directory. Future<Directory> makeDirectory(DOMString name); // Asynchronously returns a File or Directory. If the entry is a File // then get() is a shortcut for openForReading().getFile() Future<File or Directory> get(DOMString name); // Deletes a file or directory; Asynchronously returns boolean true or false // to indicate success. Future<boolean> remove(DOMString name); // Atomically renames a file or directory; Asynchronously returns boolean // true or false to indicate success. Future<boolean> rename(DOMString oldName, DOMString newName); // alternative method for rename(): // Atomically moves or renames a file or directory; Asynchronously returns // boolean true or false to indicate success. Future<boolean> moveTo((DOMString or File or Directory) entry, DOMString newName, optional Directory newParentDirectory); // TODO: maybe add copyTo() method // Asynchronously returns a FileHandle; error if called on a Directory. // If a File is passed, it must be a descendant of this directory. Future<FileHandle> openRead((DOMString or File) file); // Asynchronously returns a FileHandleWritable; // error if called on a Directory. // If a File is passed, it must be a descendant of this directory. Future<FileHandleWritable> openWrite((DOMString or File) file); // Asynchronously returns a FileHandleWritable; // error if called on a Directory. // If a File is passed, it must be a descendant of this directory. Future<FileHandleWritable> openAppend((DOMString or File) file); // alternative method for openRead(), openWrite(), openAppend(): Future<(FileHandle or FileHandleWritable)> open((DOMString or File) file, optional FileOpenMode mode); // TODO: Solve futures way of doing a cursor-style API // Asynchronously returns File or Directory objects. CursorFuture<File or Directory> enumerateShallow(); // or readEntries(); // Asynchronously returns File objects CursorFuture<File> enumerateDeep(); // or readEntriesRecursively(); }; The FileHandle/FileHandleWritable interface, representing a file open in read, write or append mode. dictionary MetadataParameters { boolean size = false; boolean lastModified = false; }; interface FileHandle { // "read" or "write" or "append" readonly attribute FileOpenMode mode; readonly attribute boolean active; // Offset in the file. This value is changed automatically after every read // and every write. Reads and writes always start at the location. // null means end-of-file attribute any location; // Upon success, you receive a read-only "snapshot" of the file's content in // the form of a File instance (that can be used anywhere a Blob is accepted, // like FileReader, XMLHttpRequest, IndexedDB, etc). Future<File> getFile(); // Asynchronously returns an ArrayBuffer of the given size. The operation // starts at the location. Moving the location by the number of bytes read. ProgressFuture<ArrayBuffer> readAsArrayBuffer(unsigned long long size); // Asynchronously returns a string of the given size with the provided // encoding. The operation starts at the location. // Moving the location by the number of bytes read. ProgressFuture<DOMString> readAsText(unsigned long long size, optional DOMString encoding); // Asynchronously returns an object with requested metadata. Future<object> getMetadata(optional MetadataParameters parameters); // Prevents any further operations from being placed against this FileHandle. void close(); // Immediately releases the lock and stops any pending or running operations. void abort(); [SetterThrows] attribute EventHandler oncomplete; [SetterThrows] attribute EventHandler onabort; [SetterThrows] attribute EventHandler onerror; }; interface FileHandleWritable : FileHandle { // Asynchronously returns the success or the failure of the write operation. // The write starts at the location, moving the location by the number of // bytes written. ProgressFuture<boolean> write((DOMString or ArrayBuffer or ArrayBufferView or Blob) value); // Asynchronously returns the success or the failure of the truncate // operation. Future<boolean> truncate(optional unsigned long long size); // Asynchronously returns the success or the failure of the flush operation. // This forces the buffered data to be transferred to disk. If the operation // was successful, you are guaranteed that if the application crashes or is // inadvertently interrupted, the data is on the disk. Future<boolean> flush(); }; Getting persistent filesystem URLs: partial interface URL { // Gets a persistent URL for a File, if it's part of a local filesystem; // otherwise returns null DOMString? getPersistentURL(File file); } [1] https://trac.webkit.org/wiki/MinimalFileStorage [2] https://wiki.mozilla.org/WebAPI/DeviceStorageAPI2 [3] https://wiki.mozilla.org/WebAPI/FileHandleAPI [4] https://developer.mozilla.org/en-US/docs/WebAPI/FileHandle Jan
Received on Thursday, 25 April 2013 16:18:10 UTC