File System Access API Documentation

repository·main·Indexed 20 days ago

https://github.com/wicg/file-system-access

Documentation for the File System Access API, which enables web applications to perform direct file editing, auto-saving, and directory management. It covers key interfaces like FileSystemFileHandle and FileSystemDirectoryHandle, the use of showOpenFilePicker and showDirectoryPicker, persisting handles in IndexedDB, and high-performance data access via AccessHandle and FileSystemSyncAccessHandle for the Origin Private File System (OPFS).

Tokens
8.7K
Snippets
22
Records
34
Agent score
71%

What's inside File System Access API

  1. Overview of the File System Access API

    main

    The File System Access API provides web applications with capabilities similar to native applications for interacting with the local file system. It aims to increase interoperability between web and native apps by allowing users to open, edit, and save files and directories directly.

    The API consists of three primary components:

    1. File and Directory Handles: New interfaces (intended to be named FileSystemFileHandle and FileSystemDirectoryHandle) that represent files and directories. These are a modernized version of the existing Entry API.
    2. File Writing: A modernized version of the FileWriter interface for saving changes to files.
    3. Access Entry Points: Mechanisms to obtain handles for a limited view of the local file system, such as through a file picker or by accessing well-known directories.
  2. Handle interaction between `suggestedName` and accepted file types

    main

    When using a file picker, the suggestedName option may conflict with the provided accepted file types. The following resolution logic applies:

    1. Suffix Match: If suggestedName ends with a suffix matching one of the accepted file types, the picker defaults to that file type.
    2. All Files Default: If there is no suffix match and excludeAcceptAllOption is false (or no explicit types are provided), the picker defaults to the "all files" option.
    3. Fallback to All Files: If the suggestedName does not match any accepted file types, the implementation behaves as if excludeAcceptAllOption was false and defaults to the "all files" option.

    Note: suggestedName is treated as a suggestion/hint. User agents may sanitize names (e.g., preventing certain extensions like .lnk or .local) for security reasons.

  3. File System Access API behavior in Private Browsing

    main

    In Private Browsing or "incognito" mode, the API functions similarly to regular mode with one key difference: no handles or permission grants are persistent.

    While a website can use the API to write data to disk during a private session, it will not be able to read that data again in a later session (private or regular) unless the user explicitly re-picks the same file or directory.

  4. Common use cases for the File System Access API

    main

    The API is designed to support several distinct patterns of file interaction:

    Single-file Editor

    • Opening, editing, and saving individual files.
    • Auto-saving changes during a browsing session.
    • Concurrent access (files can be opened in native and web apps at the same time).
    • Persistence (accessing the same files in future sessions).
    • Creating new files and auto-saving them to temporary locations before a final name/location is picked.

    Multi-file Editor

    • Opening a directory and representing its contents as a hierarchical tree.
    • Finding and editing multiple files and sub-directories within that tree.
    • Accessing new files created in the directory by other applications after the root directory was opened.

    File Libraries

    • Opening directories containing large collections of files (e.g., photo or music managers).
    • Monitoring or accessing files within a library, including new files added by other applications.
  5. How the Cloud Identifier API works

    main

    The Cloud Identifier API acts as a bridge between a web application and a Cloud Storage Provider's (CSP) local sync client.

    The Workflow:

    1. Registration: A CSP client registers itself with the browser, providing its executable path and the directories it syncs.
    2. Request: The web app calls getCloudIdentifiers() on a FileSystemHandle.
    3. Discovery: The browser identifies registered CSP clients that manage the file's path.
    4. Token Exchange: The browser launches the CSP's local executable, passing the file path and the web app's origin. The CSP client then requests a token from the CSP backend and returns it to the browser.
    5. Resolution: The browser bundles these tokens into FileSystemCloudIdentifier objects and resolves the promise.

    Important Limitations:

    • The API does not provide permissions to the files.
    • The API does not allow you to interact with (fetch/modify) the files directly via the browser; you must use the CSP's own backend APIs with the provided id.
    • The API does not provide metadata like sync status.
  6. Handle interaction between `startIn` and `id`

    main

    Both startIn and id influence the starting directory of a file picker. If both are provided, precedence is determined by the type of startIn:

    • If startIn is a well-known directory: The id takes precedence. If a previously recorded path for that id exists, it is used. If no path is known for that id, the well-known directory from startIn is used.
    • If startIn is a file or directory handle: startIn takes precedence over id. The picker starts in the directory specified by the handle, and this new directory is recorded as the last-used directory for the given id for future invocations.
  7. Security and Privacy constraints of the File System Access API

    main

    The File System Access API is designed with several security and privacy guardrails:

    • Explicit User Consent: No files or directories are exposed unless the user explicitly selects them via a picker.
    • Secure Contexts Only: The API is only available in secure contexts (HTTPS).
    • Third-Party Restrictions: Third-party iframes (cross-origin from the top-level frame) cannot trigger native pickers or permission prompts. They can only access data previously granted to them by a top-level same-origin frame.
    • Platform Protection: User agents may maintain a block list of sensitive directories (e.g., browser profile directories or platform configuration data) to prevent accidental exposure.
    • Sensor Access: The API does not grant access to device sensors unless those sensors are exposed as files or directories by the underlying platform (and even then, user agents are encouraged to block such access, e.g., /dev on Linux).
  8. Goals and Non-goals of the File System Access API

    main

    Goals

    • Interoperability: Enable web applications to operate on the native file system like native desktop applications.
    • Collaboration: Allow web apps to share and collaborate on data via the file system with other native apps.
    • Seamless Storage: Allow websites to access certain directories without an immediate user prompt, enabling them to save data to disk before a user explicitly picks a location (useful for auto-save and automated testing).

    Non-goals (Current Scope)

    • Access to the full file system.
    • Subscribing to file change notifications.
    • Extensive file metadata management (e.g., marking files as executable or hidden).
    • Integration with the <input type="file"> element.
  9. Use AccessHandle for performant data access in OPFS

    main

    The AccessHandle API provides high-performance, in-place, and exclusive write access to files within the Origin Private File System (OPFS). It is designed for use cases like Wasm-based databases (e.g., SQLite) or media processing where direct buffered access is required.

    Key Features

    • Exclusive Write Lock: Creating an AccessHandle prevents other access handles or WritableFileStreams from being created, ensuring data consistency.
    • Unflushed Reads: You can consistently read data that has been written but not yet persisted to disk via flush().
    • Zero-Copy Potential: In the asynchronous surface, it uses SharedArrayBuffer and BYOB (Bring Your Own Buffer) readers to avoid data copies.
    • Persistence: Changes are not guaranteed to be persistent until flush() is called.
    // In all contexts
    const accessHandle = await fileHandle.createAccessHandle();
    await accessHandle.writable.getWriter().write(buffer);
    const reader = accessHandle.readable.getReader({ mode: "byob" });
    // Assumes seekable streams and SharedArrayBuffer support are available
    await reader.read(buffer, { at: 1 });
  10. Security and privacy considerations for Cloud Identifiers

    main

    When using Cloud Identifiers, developers should be aware of two primary security and privacy implications:

    Fingerprinting Risks

    If a Cloud Service Provider (CSP) provides stable identifiers, web applications could potentially use them for fingerprinting the files or directories they have access to.

    While existing methods like hashing file contents or using FileSystemHandle.getUniqueId() are available, they are less stable:

    • Hashing contents: The identifier changes whenever the file content changes.
    • FileSystemHandle.getUniqueId(): This identifier is reset when the user clears their browsing data.

    Furthermore, fingerprinting via Cloud Identifiers requires the web application to have repeated access to the same FileSystemHandle, either through re-granting access or by storing the handle in IndexedDB (which is also subject to being cleared by the user).

    Modification via read-only permission

    A web application might only hold read permission for a FileSystemHandle locally, but if that same file is accessible via CSP backend APIs with write permissions, the application could modify the cloud-stored version. This modification would then sync to the device. However, in a scenario where a user has a sync client, they have implicitly allowed local files to be modified by the cloud state.

  11. Persistence and state management for file handles

    main

    Websites can persist access to files and directories across sessions using the following patterns:

    • IndexedDB Storage: You can store file or directory handles in IndexedDB. This allows a website to re-prompt for access to the same files in future visits.
    • PWA vs. Drive-by Web:
      • For installed PWAs, permission grants and handles can be persisted.
      • For drive-by web (standard websites), access is typically only valid for the duration of the session, requiring re-prompting on subsequent visits.
    • User Revocation: Users can clear storage (removing handles from IndexedDB) or revoke permissions to terminate access.
    • User-Owned Data: If you write data to a file using this API, that data is considered owned by the user. Clearing browser data will not delete these files, but the website will lose access to them until the user re-selects them.
  12. Understand AccessHandle locking semantics

    main

    Creating an AccessHandle implements an exclusive lock on the file to prevent concurrent modifications from different execution contexts.

    Lock Rules

    • createAccessHandle(): Takes an exclusive write lock. This prevents the creation of any other AccessHandle or FileSystemWritableFileStream until the handle is closed.
    • createWritable(): Takes a shared write lock. This blocks the creation of AccessHandles, but allows multiple WritableFileStreams to exist simultaneously.
    • Releasing the lock: The lock is released when accessHandle.close() is called.

    Error Handling

    If you attempt to create an access handle while one is already active, the operation will fail (throw an error).

    const accessHandle1 = await fileHandle.createAccessHandle();
    try {
      const accessHandle2 = await fileHandle.createAccessHandle();
    } catch (e) {
      // This catch will always be executed, since an open access handle exists
    }
    await accessHandle1.close();
    // Now a new access handle may be created