파일 시스템

현행 표준 — 마지막 갱신

참여:
GitHub whatwg/fs (새 이슈, 열린 이슈)
Matrix에서 채팅
커밋:
GitHub whatwg/fs/commits
이 커밋 시점의 스냅샷
@whatfilesystem
테스트:
web-platform-tests fs/ (진행 중인 작업)
번역 (비권위적):
日本語
简体中文
한국어

개요

파일 시스템은 파일 시스템을 위한 기반 구조와 API를 정의합니다.

1. 소개

이 섹션은 비규범적입니다.

이 문서는 파일 시스템 API를 위한 기본 인프라를 정의합니다. 또한, 사용자가 액세스를 요청하기 전에 웹사이트가 파일 시스템 디렉토리에 액세스할 수 있도록 하는 API를 정의합니다. 이는 웹사이트가 사용자가 저장 위치를 선택하기 전에 데이터를 디스크에 저장하려는 경우 완전히 다른 저장 메커니즘과 API를 사용하도록 강제하지 않고도 이를 가능하게 합니다. 이의 진입점은 navigator.storage.getDirectory() 메서드입니다.

2. 파일 및 디렉토리

2.1. 개념

파일 시스템 항목파일 항목 또는 디렉토리 항목 중 하나입니다.

파일 시스템 항목은 연관된 쿼리 액세스 알고리즘을 가지며, 이는 "read" 또는 "readwrite" mode를 받아 파일 시스템 액세스 결과를 반환합니다. 별도로 명시되지 않은 경우, 이는 파일 시스템 액세스 결과를 반환하며, 권한 상태가 "denied" 이고 오류 이름이 빈 문자열인 경우입니다.

파일 시스템 항목은 연관된 요청 액세스 알고리즘을 가지며, 이는 "read" 또는 "readwrite" mode를 받아 파일 시스템 액세스 결과를 반환합니다. 별도로 명시되지 않은 경우, 이는 파일 시스템 액세스 결과를 반환하며, 권한 상태가 "denied" 이고 오류 이름이 빈 문자열인 경우입니다.

파일 시스템 액세스 결과구조체로 파일 시스템에 대한 쿼리 또는 요청 결과를 캡슐화합니다. 이는 다음과 같은 항목을 포함합니다:

권한 상태

PermissionState

오류 이름

문자열로, 만약 권한 상태가 "granted" 일 경우 빈 문자열이어야 합니다. 그렇지 않은 경우, 이름으로 DOMException 이름 테이블에 나열된 항목이어야 합니다. 대부분의 경우, 권한 상태가 "granted" 가 아닌 경우, 이는 "NotAllowedError"여야 합니다.

종속 명세는 이 API를 강력한 기능으로 간주할 수 있습니다. 그러나, 다른 강력한 기능과 달리 권한 요청 알고리즘이 예외를 발생시킬 수 있는 경우, 파일 시스템 항목쿼리 액세스요청 액세스 알고리즘은 병렬로 파일 시스템 큐에서 실행되어야 하며, 따라서 예외를 발생시킬 수 없습니다. 대신, 호출자가 적절히 저장 작업을 큐에 추가하여 거부하도록 해야 하며, 이러한 알고리즘이 빈 문자열이 아닌 오류 이름을 반환할 경우 이를 처리해야 합니다.

참고: 이 명세만 구현하고 종속 명세를 구현하지 않는 경우 파일 시스템 항목쿼리 액세스요청 액세스를 구현할 필요가 없습니다.

FileSystemHandle과 관련된 액세스 확인 알고리즘을 만들 필요가 있습니다. [Issue #101]

파일 시스템 항목은 연관된 이름을 가집니다 (문자열).

유효한 파일 이름문자열로, 빈 문자열이 아니고 "." 또는 ".."와 같지 않으며, '/' 또는 기본 플랫폼에서 경로 구분자로 사용되는 다른 문자를 포함하지 않아야 합니다.

참고: 이는 Windows에서 이름에 '\'를 허용하지 않음을 의미하지만, 다른 운영 체제에서는 허용될 수 있습니다. 또한, 기본 파일 시스템은 이름에 대해 추가적인 제한을 가질 수 있으므로, 문자열이 단순히 유효한 파일 이름이라고 해서 해당 이름으로 파일이나 디렉토리를 생성할 수 있다는 보장은 없습니다.

이 API를 사용하여 결코 허용되지 않을 파일 이름에 대해 추가적인 규범적 제한을 고려해야 하며, 이를 기본 파일 시스템에 전적으로 맡기지 않아야 합니다.

파일 항목은 추가적으로 바이너리 데이터 (바이트 시퀀스), 수정 타임스탬프 (유닉스 에포크 이후 밀리초를 나타내는 숫자), 잠금 (문자열로 "open", "taken-exclusive" 또는 "taken-shared" 중 하나일 수 있음), 그리고 공유 잠금 수 (주어진 시점에 취해진 공유 잠금의 수를 나타내는 숫자)로 구성됩니다.

사용자 에이전트는 파일 시스템 큐를 가지며, 이는 새 병렬 큐 시작의 결과입니다. 이 큐는 모든 파일 시스템 작업에 사용됩니다.

잠금을 취득하려면, 주어진 잠금value 값 "exclusive" 또는 "shared"로 설정합니다. 파일 항목 file에 대해:
  1. lockfile잠금으로 설정합니다.

  2. countfile공유 잠금 수로 설정합니다.

  3. 만약 value가 "exclusive"라면:

    1. 만약 lock이 "open"이라면:

      1. 잠금을 "taken-exclusive"로 설정합니다.

      2. "success"를 반환합니다.

  4. 만약 value가 "shared"라면:

    1. 만약 lock이 "open"이라면:

      1. lock을 "taken-shared"로 설정합니다.

      2. count를 1로 설정합니다.

      3. "success"를 반환합니다.

    2. 그 외에, 만약 lock이 "taken-shared"이라면:

      1. count를 1 증가시킵니다.

      2. "success"를 반환합니다.

  5. "failure"를 반환합니다.

참고: 이 단계는 파일 시스템 큐에서 실행되어야 합니다.

잠금 해제하려면, 주어진 잠금파일 항목 file에서 해제합니다:
  1. lockfile의 연관된 잠금으로 설정합니다.

  2. countfile공유 잠금 수로 설정합니다.

  3. 만약 lock이 "taken-shared"이라면:

    1. count를 1 감소시킵니다.

    2. 만약 count가 0이라면, lock을 "open"으로 설정합니다.

  4. 그 외에는, lock을 "open"으로 설정합니다.

참고: 이 단계는 파일 시스템 큐에서 실행되어야 합니다.

참고: 잠금은 파일의 동시 수정 방지를 돕습니다. FileSystemWritableFileStream 은 공유 잠금이 필요하고, FileSystemSyncAccessHandle 은 배타적 잠금이 필요합니다.

디렉토리 항목은 추가적으로 집합으로 구성된 자식 항목을 포함하며, 이들은 파일 시스템 항목이 됩니다. 각 멤버는 파일 항목이거나 디렉토리 항목입니다.

파일 시스템 항목 entry는 최대 하나의 자식 항목 안에 포함되어야 하며, 해당 디렉토리 항목은 entry부모로 알려집니다. 파일 시스템 항목부모가 존재하지 않을 경우 null이 됩니다.

참고: 서로 다른 두 파일 시스템 항목이 디스크에서 동일한 파일이나 디렉토리를 나타낼 수 있으며, 이 경우 두 항목이 서로 다른 부모를 가질 수도 있고, 하나의 항목만 부모를 가질 수도 있습니다.

파일 시스템 항목은 (필수는 아니지만) 호스트 운영 체제의 로컬 파일 시스템에 의해 지원될 수 있으므로, 바이너리 데이터, 수정 타임스탬프, 그리고 자식 항목이 이 명세 외부의 응용 프로그램에 의해 수정될 가능성이 있습니다. 외부 변경 사항이 이 명세에서 정의된 데이터 구조에 반영되는 방식과, 이 명세에서 정의된 데이터 구조에 대한 변경 사항이 외부에 반영되는 방식은 개별 사용자 에이전트 구현에 맡겨집니다.

파일 시스템 항목 a동일한 항목으로 간주됩니다. 파일 시스템 항목 ba와 동일하거나, ab가 로컬 파일 시스템에서 동일한 파일 또는 디렉토리를 지원하는 경우입니다.

해결하려면 파일 시스템 로케이터 child디렉토리 로케이터 root에 상대적으로 설정합니다:

  1. result새로운 프라미스로 설정합니다.

  2. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. 만약 child로케이터루트root로케이터루트와 다르다면, 해결 result를 null로 설정하고, 단계를 중지합니다.

    2. childPathchild로케이터경로로 설정합니다.

    3. rootPathroot로케이터경로로 설정합니다.

    4. 만약 childPath동일한 경로라면 rootPath, 해결 result를 « »로 설정하고, 단계를 중지합니다.

    5. 만약 rootPath크기childPath크기보다 크다면, 해결 result를 null로 설정하고, 단계를 중지합니다.

    6. 각각index에 대해 rootPath인덱스를 반복합니다:

      1. 만약 rootPath.[[index]]가 childPath.[[index]]와 다르다면, 해결 result를 null로 설정하고, 단계를 중지합니다.

    7. relativePath를 « »로 설정합니다.

    8. 각각index에 대해 범위를 반복합니다. rootPath크기에서 시작하여, rootPath크기까지 독점적으로 반복하며, 추가 childPath.[[index]]를 relativePath에 설정합니다.

    9. 해결 resultrelativePath로 설정합니다.

  3. result를 반환합니다.

파일 시스템 로케이터파일 시스템 항목의 잠재적 위치를 나타냅니다. 파일 시스템 로케이터파일 로케이터 또는 디렉토리 로케이터 중 하나입니다.

파일 시스템 로케이터는 연관된 경로 (파일 시스템 경로), 종류 (FileSystemHandleKind), 그리고 루트 (파일 시스템 루트)를 가집니다.

각각의 로케이터에 스토리지 버킷을 제공하는 것을 고려하십시오. [Issue #109]

파일 로케이터파일 시스템 로케이터로, 종류가 "file"인 경우입니다. 디렉토리 로케이터파일 시스템 로케이터로, 종류가 "directory"인 경우입니다.

파일 시스템 루트는 불투명한 문자열로, 그 값은 구현 정의입니다.

파일 시스템 로케이터 locator위치하는 파일 항목 entry가 개념적으로 버킷 파일 시스템의 루트 디렉토리에서 경로 data/drafts/example.txt에 존재한다고 가정합니다. locator종류는 "file"여야 하며, locator경로는 « "data", "drafts", "example.txt" »여야 하며, locator루트에는 스토리지 버킷 및 디스크 드라이브와 같은 관련 식별 정보가 포함될 수 있습니다.

파일 시스템 로케이터 a파일 시스템 로케이터 b동일한 로케이터로 간주됩니다. a종류b종류와 동일하고, a루트b루트와 동일하며, a경로동일한 경로b경로와 동일한 경우입니다.

항목 찾기 알고리즘은 파일 시스템 로케이터 locator를 입력으로 받아 구현 정의된 일련의 단계를 실행하며 다음 제약 조건을 따릅니다:
로케이터 가져오기 알고리즘은 파일 시스템 항목 entry를 입력으로 받아 구현 정의된 일련의 단계를 실행하며 다음 제약 조건을 따릅니다:

파일 시스템 경로하나 이상의 항목으로 이루어진 목록이며, 각각은 문자열입니다. 이는 디스크나 메모리의 실제 위치에 매핑된 가상 경로일 수도 있고, 로컬 파일 시스템의 경로와 직접적으로 대응하거나, 디스크에 있는 파일과 전혀 대응하지 않을 수도 있습니다. 해당 파일 시스템 항목의 실제 물리적 위치는 구현 정의입니다.

path목록 « "data", "drafts", "example.txt" »로 설정합니다. 디스크 어디에도 example.txt라는 이름의 파일이 존재해야 한다는 기대는 없습니다.

파일 시스템 경로 a파일 시스템 경로 b동일한 경로로 간주됩니다. a크기b크기와 동일하고, index에 대해 a인덱스에서 a.[[index]]가 b.[[index]]와 동일한 경우입니다.

파일 시스템 로케이터의 내용, 특히 경로는 웹사이트 프로세스와 완전히 공유될 것으로 기대되지 않습니다. 파일 시스템 경로파일 시스템 로케이터가 나중에 부모 디렉토리 로케이터에 상대적으로 해결되지 않는 한, 웹사이트에 알려지지 않은 구성 요소를 포함할 수 있습니다.

2.2. FileSystemHandle 인터페이스

enum FileSystemHandleKind {
  "file",
  "directory",
};

[Exposed=(Window,Worker), SecureContext, Serializable]
interface FileSystemHandle {
  readonly attribute FileSystemHandleKind kind;
  readonly attribute USVString name;

  Promise<boolean> isSameEntry(FileSystemHandle other);
};

FileSystemHandle 객체는 로케이터 (파일 시스템 로케이터)와 연관됩니다.

참고: 여러 FileSystemHandle 객체가 동일한 파일 시스템 로케이터를 가질 수 있습니다.

FileSystemHandle 버킷 파일 시스템에 존재합니다. 이 경우, 해당 로케이터경로의 첫 번째 항목이 빈 문자열입니다.

참고: 이는 다소 마술적이지만, 버킷 파일 시스템의 루트 디렉토리만이 경로에 빈 문자열을 포함할 수 있기 때문에 작동합니다. getDirectory()를 참조하세요. 다른 항목은 모두 유효한 파일 이름이 됩니다.

각각의 로케이터에 스토리지 버킷을 할당하는 방안을 고려하세요. [Issue #109]

FileSystemHandle 객체는 직렬화 가능한 객체입니다.

주어진 value, serialized, forStorage에 대해 직렬화 단계는 다음과 같습니다:

  1. serialized.[[Origin]]을 value관련 설정 객체원점으로 설정합니다.

  2. serialized.[[Locator]]를 value로케이터로 설정합니다.

역직렬화 단계는 주어진 serialized, value에 대해 다음과 같습니다:
  1. 만약 serialized.[[Origin]]이 value관련 설정 객체원점같은 원점이 아니라면, "DataCloneError" DOMException발생시킵니다.

  2. value로케이터serialized.[[Locator]]로 설정합니다.

handle . kind

만약 handleFileSystemFileHandle이라면 "file"을 반환하고, handleFileSystemDirectoryHandle이라면 "directory"를 반환합니다.

이는 디렉토리 내용을 순회할 때 파일과 디렉토리를 구분하는 데 사용될 수 있습니다.

handle . name

handle로케이터경로의 마지막 구성 요소를 반환합니다.

kind getter 단계는 this로케이터종류를 반환하는 것입니다.

name getter 단계는 this로케이터경로의 마지막 항목 (a 문자열)을 반환하는 것입니다.

2.2.1. isSameEntry() 메서드

same = await handle1 . isSameEntry( handle2 )

handle1handle2가 동일한 파일 또는 디렉토리를 나타내는 경우 true를 반환합니다.

isSameEntry(other) 메서드 단계는 다음과 같습니다:
  1. realmthis관련 Realm으로 설정합니다.

  2. p새로운 프라미스realm에 설정합니다.

  3. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. 만약 this로케이터other로케이터동일한 로케이터라면, resolve p를 true로 설정합니다.

    2. 그 외에는 resolve p를 false로 설정합니다.

  4. p를 반환합니다.

2.3. FileSystemFileHandle 인터페이스

dictionary FileSystemCreateWritableOptions {
  boolean keepExistingData = false;
};

[Exposed=(Window,Worker), SecureContext, Serializable]
interface FileSystemFileHandle : FileSystemHandle {
  Promise<File> getFile();
  Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWritableOptions options = {});
  [Exposed=DedicatedWorker]
  Promise<FileSystemSyncAccessHandle> createSyncAccessHandle();
};

참고: FileSystemFileHandle의 연관된 로케이터종류는 "file"입니다.

자식 FileSystemFileHandle 만들기디렉토리 로케이터 parentLocator와 문자열 name, Realm realm을 입력으로 받습니다:
  1. handle새로운 FileSystemFileHandlerealm에 설정합니다.

  2. childType을 "file"로 설정합니다.

  3. childRootparentLocator루트의 복사본으로 설정합니다.

  4. childPath복제parentLocator경로추가name의 결과로 설정합니다.

  5. handle로케이터파일 시스템 로케이터로 설정하며, 그 종류childType, 루트childRoot, 그리고 경로childPath입니다.

  6. handle을 반환합니다.

새로운 FileSystemFileHandle 만들기파일 시스템 루트 root파일 시스템 경로 path, 그리고 Realm realm을 입력으로 받습니다:
  1. handle새로운 FileSystemFileHandlerealm에 설정합니다.

  2. handle로케이터파일 시스템 로케이터로 설정하며, 그 종류는 "file", 루트root, 그리고 경로path입니다.

  3. handle을 반환합니다.

FileSystemFileHandle 객체는 직렬화 가능한 객체입니다. 그 직렬화 단계역직렬화 단계FileSystemHandle과 동일합니다.

2.3.1. getFile() 메서드

file = await fileHandle . getFile()

handle로케이터위치를 확인할 수 있는 파일 항목의 디스크 상태를 나타내는 File을 반환합니다. 이 메서드가 호출된 후 디스크의 파일이 변경되거나 삭제되면, 반환된 File 객체는 더 이상 읽을 수 없게 될 가능성이 높습니다.

getFile() 메서드 단계는 다음과 같습니다:
  1. result새로운 프라미스로 설정합니다.

  2. locatorthis로케이터로 설정합니다.

  3. globalthis관련 전역 객체로 설정합니다.

  4. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. entrylocator를 입력으로 받아 항목 찾기의 결과로 설정합니다.

    2. accessResult를 "read"를 입력으로 하여 entry쿼리 액세스를 실행한 결과로 설정합니다.

    3. 저장 작업을 큐에 추가하여 global에서 다음 단계를 실행합니다:

      1. 만약 accessResult권한 상태가 "granted"가 아니라면, accessResult오류 이름으로 result거부하고 이 단계를 중단합니다.

      2. 만약 entry가 null이라면, result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

      3. 단언: entry파일 항목입니다.

      4. f를 새로운 File로 설정합니다.

      5. f스냅샷 상태entry의 현재 상태로 설정합니다.

      6. f의 기본 바이트 시퀀스를 entry바이너리 데이터의 복사본으로 설정합니다.

      7. fnameentry이름으로 설정합니다.

      8. flastModifiedentry수정 타임스탬프로 설정합니다.

      9. ftype구현 정의된 값으로 설정하며, 이는 예를 들어 entry이름이나 파일 확장자를 기반으로 합니다.

        읽기 및 스냅샷 생성 동작은 [FILE-API] 명세에서 더 명확히 정의되어야 하며, 현재로서는 다소 모호합니다.

      10. resultf해결합니다.

  5. result를 반환합니다.

2.3.2. createWritable() 메서드

stream = await fileHandle . createWritable()
stream = await fileHandle . createWritable({ keepExistingData: true/false })

FileSystemWritableFileStream 을 반환하며, 이를 사용하여 파일에 기록할 수 있습니다. stream을 통해 수행한 변경 사항은 fileHandle로케이터위치를 확인할 수 있는 파일 항목에 스트림이 닫힐 때까지 반영되지 않습니다. 사용자는 부분 쓰기가 발생하지 않도록 보장하려고 시도합니다. 즉, 파일은 이전 내용이거나 스트림이 닫힐 때까지 stream을 통해 기록된 데이터를 포함합니다.

이는 일반적으로 데이터를 임시 파일에 기록한 다음, 기록 가능한 파일 스트림이 닫힐 때 fileHandle로케이터위치를 확인할 수 있는 파일 항목을 임시 파일로 교체하는 방식으로 구현됩니다.

만약 keepExistingData 가 false이거나 지정되지 않은 경우, 임시 파일은 비어 있는 상태로 시작하며, 그렇지 않으면 기존 파일이 먼저 이 임시 파일로 복사됩니다.

FileSystemWritableFileStream 을 생성하면 파일 항목에서 공유 잠금을 가져옵니다. 이는 스트림이 닫힐 때까지 해당 항목에 대해 FileSystemSyncAccessHandles 의 생성을 방지합니다.

createWritable에 대한 "inPlace" 모드(변경 사항이 작성자에 기록되는 대로 실제 기본 파일에 기록되는 모드)를 구현하기 위한 논의는 WICG/file-system-access issue #67에서 확인할 수 있습니다. 이는 현재 Chrome에서 구현되지 않았습니다. 이를 구현하는 데에는 맬웨어 검사를 실행하려는 요구와 기존 대형 파일에 대해 웹사이트가 빠르게 변경을 수행할 수 있도록 하려는 요구를 결합하는 방법을 찾는 것이 장애물로 작용하고 있습니다. 버킷 파일 시스템의 파일은 FileSystemSyncAccessHandle 인터페이스를 통해 인플레이스 쓰기가 가능합니다.

createWritable(options) 메서드 단계는 다음과 같습니다:
  1. result새로운 프라미스로 설정합니다.

  2. locatorthis로케이터로 설정합니다.

  3. realmthis관련 Realm으로 설정합니다.

  4. globalthis관련 전역 객체로 설정합니다.

  5. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. entrylocator를 입력으로 받아 항목 찾기의 결과로 설정합니다.

    2. accessResult를 "readwrite"를 입력으로 하여 entry요청 액세스를 실행한 결과로 설정합니다.

    3. 만약 accessResult권한 상태가 "granted"가 아니라면, global에서 저장 작업을 큐에 추가하여 accessResult오류 이름으로 result거부하고 이 단계를 중단합니다.

    4. 만약 entrynull이라면, global에서 저장 작업을 큐에 추가하여 result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

    5. 단언: entry파일 항목입니다.

    6. lockResultentry에 대해 "shared"를 입력으로 하여 잠금 가져오기의 결과로 설정합니다.

    7. global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. 만약 lockResult가 "failure"라면, result를 "NoModificationAllowedError" DOMException으로 거부하고 이 단계를 중단합니다.

      2. streamentry에 대해 realm에서 새로운 FileSystemWritableFileStream 생성의 결과로 설정합니다.

      3. 만약 options["keepExistingData"] 가 true라면:

        1. stream[[buffer]]entry바이너리 데이터의 복사본으로 설정합니다.

      4. resultstream으로 해결합니다.

  6. result를 반환합니다.

2.3.3. createSyncAccessHandle() 메서드

handle = await fileHandle . createSyncAccessHandle()

FileSystemSyncAccessHandle 을 반환하며, 이를 사용하여 파일을 읽거나 쓸 수 있습니다. handle을 통해 수행한 변경 사항은 fileHandle로케이터위치를 확인할 수 있는 파일 항목에 즉시 반영될 수 있습니다. 이러한 변경 사항을 파일에 반영하려면 핸들을 플러시할 수 있습니다.

FileSystemSyncAccessHandle 을 생성하면 fileHandle로케이터위치를 확인할 수 있는 파일 항목에 대해 배타적 잠금을 가져옵니다. 이로 인해 액세스 핸들이 닫힐 때까지 해당 항목에 대해 추가 FileSystemSyncAccessHandles 또는 FileSystemWritableFileStreams 생성이 방지됩니다.

반환된 FileSystemSyncAccessHandle 은 동기 메서드를 제공합니다. 이는 비동기 작업에 높은 오버헤드가 있는 WebAssembly와 같은 컨텍스트에서 더 높은 성능을 제공합니다.

현재 이 메서드는 fileHandle버킷 파일 시스템에 존재하는 경우에만 성공합니다.

createSyncAccessHandle() 메서드 단계는 다음과 같습니다:
  1. result새로운 프라미스로 설정합니다.

  2. locatorthis로케이터로 설정합니다.

  3. realmthis관련 Realm으로 설정합니다.

  4. globalthis관련 전역 객체로 설정합니다.

  5. isInABucketFileSystemthis버킷 파일 시스템에 존재한다면 true로 설정하고, 그렇지 않으면 false로 설정합니다.

  6. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. entrylocator를 입력으로 받아 항목 찾기의 결과로 설정합니다.

    2. accessResult를 "readwrite"를 입력으로 하여 entry요청 액세스를 실행한 결과로 설정합니다.

    3. 만약 accessResult권한 상태가 "granted"가 아니라면, global에서 저장 작업을 큐에 추가하여 accessResult오류 이름으로 result거부하고 이 단계를 중단합니다.

    4. 만약 isInABucketFileSystem이 false라면, global에서 저장 작업을 큐에 추가하여 result를 "InvalidStateError" DOMException으로 거부하고 이 단계를 중단합니다.

    5. 만약 entrynull이라면, global에서 저장 작업을 큐에 추가하여 result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

    6. 단언: entry파일 항목입니다.

    7. lockResultentry에 대해 "exclusive"를 입력으로 하여 잠금 가져오기의 결과로 설정합니다.

    8. global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. 만약 lockResult가 "failure"라면, result를 "NoModificationAllowedError" DOMException으로 거부하고 이 단계를 중단합니다.

      2. handleentry에 대해 realm에서 새로운 FileSystemSyncAccessHandle 생성의 결과로 설정합니다.

      3. resulthandle으로 해결합니다.

  7. result를 반환합니다.

2.4. FileSystemDirectoryHandle 인터페이스

dictionary FileSystemGetFileOptions {
  boolean create = false;
};

dictionary FileSystemGetDirectoryOptions {
  boolean create = false;
};

dictionary FileSystemRemoveOptions {
  boolean recursive = false;
};

[Exposed=(Window,Worker), SecureContext, Serializable]
interface FileSystemDirectoryHandle : FileSystemHandle {
  async_iterable<USVString, FileSystemHandle>;

  Promise<FileSystemFileHandle> getFileHandle(USVString name, optional FileSystemGetFileOptions options = {});
  Promise<FileSystemDirectoryHandle> getDirectoryHandle(USVString name, optional FileSystemGetDirectoryOptions options = {});

  Promise<undefined> removeEntry(USVString name, optional FileSystemRemoveOptions options = {});

  Promise<sequence<USVString>?> resolve(FileSystemHandle possibleDescendant);
};

참고: FileSystemDirectoryHandle의 연관된 로케이터종류는 "directory"입니다.

자식 FileSystemDirectoryHandle 생성디렉토리 로케이터 parentLocator와 문자열 name, Realm realm을 입력으로 받습니다:
  1. handle새로운 FileSystemDirectoryHandlerealm에 설정합니다.

  2. childType을 "directory"로 설정합니다.

  3. childRootparentLocator루트의 복사본으로 설정합니다.

  4. childPath복제parentLocator경로추가name의 결과로 설정합니다.

  5. handle로케이터파일 시스템 로케이터로 설정하며, 그 종류childType, 루트childRoot, 그리고 경로childPath입니다.

  6. handle을 반환합니다.

새로운 FileSystemDirectoryHandle 생성파일 시스템 루트 root파일 시스템 경로 path, 그리고 Realm realm을 입력으로 받습니다:
  1. handle새로운 FileSystemDirectoryHandlerealm에 설정합니다.

  2. handle로케이터파일 시스템 로케이터로 설정하며, 그 종류는 "directory", 루트root, 그리고 경로path입니다.

  3. handle을 반환합니다.

FileSystemDirectoryHandle 객체는 직렬화 가능한 객체입니다. 그 직렬화 단계역직렬화 단계FileSystemHandle과 동일합니다.

2.4.1. 디렉토리 반복

for await (let [name, handle] of directoryHandle) {}
for await (let [name, handle] of directoryHandle . entries()) {}
for await (let handle of directoryHandle . values()) {}
for await (let name of directoryHandle . keys()) {}

directoryHandle로케이터위치를 확인할 수 있는 디렉토리 항목을 부모로 가지는 모든 항목을 반복합니다. 반복이 진행되는 동안 생성되거나 삭제된 항목은 포함될 수도 있고 포함되지 않을 수도 있습니다. 어느 쪽이든 보장되지 않습니다.

향후 비동기 반복 선언에 재귀적 반복과 같은 지원을 추가하기 위해 매개변수를 추가할 수 있습니다. [Issue #15]

비동기 반복 초기화 단계FileSystemDirectoryHandle handle과 그 비동기 반복자 iterator에 대해 다음과 같습니다:
  1. iterator이전 결과를 빈 집합으로 설정합니다.

FileSystemDirectoryHandle handle과 그 비동기 반복자 iterator에 대해 다음 반복 결과 얻기는 다음과 같습니다:
  1. promise새로운 프라미스로 설정합니다.

  2. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. directoryhandle로케이터를 입력으로 받아 항목 찾기의 결과로 설정합니다.

    2. accessResult를 "read"를 입력으로 하여 directory쿼리 액세스를 실행한 결과로 설정합니다.

    3. handle관련 전역 객체에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. 만약 accessResult권한 상태가 "granted"가 아니라면, accessResult오류 이름으로 promise거부하고 이 단계를 중단합니다.

      2. 만약 directorynull이라면, result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

        1. 단언: directory디렉토리 항목입니다.

      3. childdirectory자식 항목 중 하나로 설정하며, child이름iterator이전 결과에 포함되지 않은 항목이어야 합니다. 그러한 항목이 없으면 null로 설정합니다.

        참고: 이는 반복 순서에 대해 의도적으로 모호하게 정의되어 있습니다. 서로 다른 플랫폼과 파일 시스템은 반복 순서에 대해 서로 다른 보장을 제공하며, 모든 플랫폼에서 효율적으로 구현할 수 있도록 하기 위해 정확한 순서에 대한 보장은 제공되지 않습니다.

      4. 만약 childnull이라면, promiseundefined해결하고 이 단계를 중단합니다.

      5. child이름iterator이전 결과추가합니다.

      6. 만약 child파일 항목이라면:

        1. resulthandle로케이터child이름, 그리고 handle관련 Realm을 사용하여 자식 FileSystemFileHandle 생성의 결과로 설정합니다.

      7. 그 외에는:

        1. resulthandle로케이터child이름, 그리고 handle관련 Realm을 사용하여 자식 FileSystemDirectoryHandle 생성의 결과로 설정합니다.

      8. promise를 (child이름, result)로 해결합니다.

  3. promise를 반환합니다.

2.4.2. getFileHandle() 메서드

fileHandle = await directoryHandle . getFileHandle(name)
fileHandle = await directoryHandle . getFileHandle(name, { create: false })

directoryHandle로케이터위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 파일에 대한 핸들을 반환합니다. 해당 파일이 존재하지 않는 경우, 이 메서드는 거부됩니다.

fileHandle = await directoryHandle . getFileHandle(name, { create: true })

directoryHandle로케이터위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 파일에 대한 핸들을 반환합니다. 해당 파일이 존재하지 않는 경우, 새 파일을 생성합니다. name이라는 이름을 가진 파일을 생성할 수 없는 경우, 이 메서드는 거부됩니다. 생성이 실패하는 이유는 동일한 이름을 가진 디렉토리가 이미 존재하거나, 이름에 기본 파일 시스템에서 지원되지 않는 문자가 포함되었거나, 보안상의 이유로 사용자 에이전트가 파일 생성을 허용하지 않기로 결정했기 때문일 수 있습니다.

이 작업은 파일이 이미 존재하더라도 쓰기 권한이 필요합니다. 이 핸들이 이미 쓰기 권한을 가지고 있지 않으면, 사용자에게 프롬프트가 표시될 수 있습니다. 쓰기 권한 없이 기존 파일을 가져오려면 이 메서드를 { create: false }로 호출하세요.

getFileHandle(name, options) 메서드 단계는 다음과 같습니다:
  1. result새로운 프라미스로 설정합니다.

  2. realmthis관련 Realm으로 설정합니다.

  3. locatorthis로케이터로 설정합니다.

  4. globalthis관련 전역 객체로 설정합니다.

  5. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. 만약 name유효한 파일 이름이 아니라면, global에서 저장 작업을 큐에 추가하여 resultTypeError거부하고 이 단계를 중단합니다.

    2. entrylocator를 입력으로 받아 항목 찾기의 결과로 설정합니다.

    3. 만약 options["create"] 가 true라면:

      1. accessResult를 "readwrite"를 입력으로 하여 entry요청 액세스를 실행한 결과로 설정합니다.

    4. 그 외에는:

      1. accessResult를 "read"를 입력으로 하여 entry쿼리 액세스를 실행한 결과로 설정합니다.

    5. global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. 만약 accessResult권한 상태가 "granted"가 아니라면, accessResult오류 이름으로 result거부하고 이 단계를 중단합니다.

      2. 만약 entrynull이라면, result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

      3. 단언: entry디렉토리 항목입니다.

      4. entry자식 항목각각 child에 대해 반복합니다:

        1. 만약 child이름name과 같다면:

          1. 만약 child디렉토리 항목이라면:

            1. result를 "TypeMismatchError" DOMException으로 거부하고 이 단계를 중단합니다.

          2. resultlocatorchild이름, realm을 사용하여 자식 FileSystemFileHandle 생성의 결과로 해결하고 이 단계를 중단합니다.

      5. 만약 options["create"] 가 false라면:

        1. result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

      6. child를 새 파일 항목으로 설정하며, child쿼리 액세스요청 액세스 알고리즘은 entry와 동일하게 합니다.

      7. child이름name으로 설정합니다.

      8. child바이너리 데이터를 빈 바이트 시퀀스로 설정합니다.

      9. child수정 타임스탬프를 현재 시간으로 설정합니다.

      10. entry자식 항목child추가합니다.

      11. 기본 파일 시스템에서 child를 생성하는 동안 예외가 발생하면, 해당 예외로 result거부하고 이 단계를 중단합니다.

        발생할 수 있는 예외를 더 잘 명시해야 합니다. [Issue #11]

      12. resultlocatorchild이름, realm을 사용하여 자식 FileSystemFileHandle 생성의 결과로 해결합니다.

  6. result를 반환합니다.

2.4.3. getDirectoryHandle() 메서드

subdirHandle = await directoryHandle . getDirectoryHandle(name)
subdirHandle = await directoryHandle . getDirectoryHandle(name, { create: false })

directoryHandle로케이터위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 디렉토리에 대한 핸들을 반환합니다. 해당 디렉토리가 존재하지 않는 경우, 이 메서드는 거부됩니다.

subdirHandle = await directoryHandle . getDirectoryHandle(name, { create: true })

directoryHandle로케이터위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 디렉토리에 대한 핸들을 반환합니다. 해당 디렉토리가 존재하지 않는 경우 새 디렉토리를 생성합니다. 디렉토리 생성이 실패하면, 이 메서드는 거부됩니다. 생성 실패의 원인은 동일한 이름을 가진 파일이 이미 존재하거나, 이름에 기본 파일 시스템에서 지원되지 않는 문자가 포함되었기 때문일 수 있습니다.

이 작업은 디렉토리가 이미 존재하더라도 쓰기 권한이 필요합니다. 이 핸들이 이미 쓰기 권한을 가지고 있지 않으면, 사용자에게 프롬프트가 표시될 수 있습니다. 쓰기 권한 없이 기존 디렉토리를 가져오려면 이 메서드를 { create: false }로 호출하세요.

getDirectoryHandle(name, options) 메서드 단계는 다음과 같습니다:
  1. result새로운 프라미스로 설정합니다.

  2. realmthis관련 Realm으로 설정합니다.

  3. locatorthis로케이터로 설정합니다.

  4. globalthis관련 전역 객체로 설정합니다.

  5. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. 만약 name유효한 파일 이름이 아니라면, global에서 저장 작업을 큐에 추가하여 resultTypeError거부하고 이 단계를 중단합니다.

    2. entrylocator를 입력으로 받아 항목 찾기의 결과로 설정합니다.

    3. 만약 options["create"] 가 true라면:

      1. accessResult를 "readwrite"를 입력으로 하여 entry요청 액세스를 실행한 결과로 설정합니다.

    4. 그 외에는:

      1. accessResult를 "read"를 입력으로 하여 entry쿼리 액세스를 실행한 결과로 설정합니다.

    5. global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. 만약 accessResult권한 상태가 "granted"가 아니라면, accessResult오류 이름으로 result거부하고 이 단계를 중단합니다.

      2. 만약 entrynull이라면, result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

      3. 단언: entry디렉토리 항목입니다.

      4. entry자식 항목각각 child에 대해 반복합니다:

        1. 만약 child이름name과 같다면:

          1. 만약 child파일 항목이라면:

            1. result를 "TypeMismatchError" DOMException으로 거부하고 이 단계를 중단합니다.

          2. resultlocatorchild이름, realm을 사용하여 자식 FileSystemDirectoryHandle 생성의 결과로 해결하고 이 단계를 중단합니다.

      5. 만약 options["create"] 가 false라면:

        1. result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

      6. child를 새 디렉토리 항목으로 설정하며, child쿼리 액세스요청 액세스 알고리즘은 entry와 동일하게 합니다.

      7. child이름name으로 설정합니다.

      8. child자식 항목을 빈 집합으로 설정합니다.

      9. entry자식 항목child추가합니다.

      10. 기본 파일 시스템에서 child를 생성하는 동안 예외가 발생하면, 해당 예외로 result거부하고 이 단계를 중단합니다.

        발생할 수 있는 예외를 더 잘 명시해야 합니다. [Issue #11]

      11. resultlocatorchild이름, realm을 사용하여 자식 FileSystemDirectoryHandle 생성의 결과로 해결합니다.

  6. result를 반환합니다.

2.4.4. removeEntry() 메서드

await directoryHandle . removeEntry(name)
await directoryHandle . removeEntry(name, { recursive: false })

directoryHandle로케이터위치를 확인할 수 있는 디렉토리 항목name이라는 이름의 파일 또는 빈 디렉토리가 포함된 경우, 해당 파일 또는 디렉토리를 삭제하려고 시도합니다.

존재하지 않는 파일이나 디렉토리를 삭제하려고 시도하는 것은 성공으로 간주되지만, 비어 있지 않은 디렉토리를 삭제하려고 하면 Promise가 거부됩니다.

await directoryHandle . removeEntry(name, { recursive: true })

directoryHandle로케이터위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 파일 시스템 항목을 삭제합니다. 해당 항목이 디렉토리인 경우, 그 내용도 재귀적으로 삭제됩니다.

존재하지 않는 파일이나 디렉토리를 삭제하려고 시도하는 것은 성공으로 간주됩니다.

removeEntry(name, options) 메서드 단계는 다음과 같습니다:
  1. result새로운 프라미스로 설정합니다.

  2. locatorthis로케이터로 설정합니다.

  3. globalthis관련 전역 객체로 설정합니다.

  4. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. 만약 name유효한 파일 이름이 아니라면, global에서 저장 작업을 큐에 추가하여 resultTypeError거부하고 이 단계를 중단합니다.

    2. entrylocator를 입력으로 받아 항목 찾기의 결과로 설정합니다.

    3. accessResult를 "readwrite"를 입력으로 하여 entry요청 액세스를 실행한 결과로 설정합니다.

    4. global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:

      1. 만약 accessResult권한 상태가 "granted"가 아니라면, accessResult오류 이름으로 result거부하고 이 단계를 중단합니다.

      2. 만약 entrynull이라면, result를 "NotFoundError" DOMException으로 거부하고 이 단계를 중단합니다.

      3. 단언: entry디렉토리 항목입니다.

      4. entry자식 항목각각 child에 대해 반복합니다:

        1. 만약 child이름name과 같다면:

          1. 만약 child디렉토리 항목이라면:

            1. 만약 child자식 항목비어 있지 않으며, options["recursive"] 가 false라면:

              1. result를 "InvalidModificationError" DOMException으로 거부하고 이 단계를 중단합니다.

          2. childentry자식 항목에서 제거합니다.

          3. 기본 파일 시스템에서 child를 제거하는 동안 예외가 발생하면, 해당 예외로 result거부하고 이 단계를 중단합니다.

            참고: recursive 가 true인 경우, 제거는 비원자적일 수 있습니다. 일부 파일 또는 디렉토리는 제거된 반면, 다른 파일 또는 디렉토리는 여전히 존재할 수 있습니다.

            발생할 수 있는 예외를 더 잘 명시해야 합니다. [Issue #11]

          4. resultundefined해결합니다.

      5. result를 "NotFoundError" DOMException으로 거부합니다.

  5. result를 반환합니다.

2.4.5. resolve() 메서드

path = await directory . resolve( child )

childdirectory와 동일하다면, path는 빈 배열이 됩니다.

childdirectory의 직접적인 자식이라면, pathchild의 이름을 포함하는 배열이 됩니다.

childdirectory의 하위 항목이라면, path는 모든 중간 디렉토리 이름과 마지막 요소로 child의 이름을 포함하는 배열이 됩니다. 예를 들어, directory/home/user/project를 나타내고 child/home/user/project/foo/bar를 나타낸다면, 이는 ['foo', 'bar']를 반환합니다.

그 외 (directorychild가 관련이 없는 경우), path는 null이 됩니다.

// 유효한 디렉토리 핸들을 얻었다고 가정합니다.
const dir_ref = current_project_dir;
if (!dir_ref) return;

// 이제 파일 참조를 가져옵니다:
const file_ref = await dir_ref.getFileHandle(filename, { create: true });

// file_ref가 dir_ref 내부에 있는지 확인합니다:
const relative_path = await dir_ref.resolve(file_ref);
if (relative_path === null) {
    // dir_ref 내부에 없습니다.
} else {
    // relative_path는 dir_ref에서 file_ref가 나타내는 파일까지의 상대 경로를 제공하는 이름 배열입니다:
    assert relative_path.pop() === file_ref.name;

    let entry = dir_ref;
    for (const name of relative_path) {
        entry = await entry.getDirectory(name);
    }
    entry = await entry.getFile(file_ref.name);

    // 이제 |entry|는 |file_ref|가 나타내는 동일한 디스크 상의 파일을 나타냅니다.
    assert await entry.isSameEntry(file_ref) === true;
}
resolve(possibleDescendant) 메서드 단계는 해결possibleDescendant로케이터this로케이터를 기준으로 반환합니다.

2.5. FileSystemWritableFileStream 인터페이스

enum WriteCommandType {
  "write",
  "seek",
  "truncate",
};

dictionary WriteParams {
  required WriteCommandType type;
  unsigned long long? size;
  unsigned long long? position;
  (BufferSource or Blob or USVString)? data;
};

typedef (BufferSource or Blob or USVString or WriteParams) FileSystemWriteChunkType;

[Exposed=(Window,Worker), SecureContext]
interface FileSystemWritableFileStream : WritableStream {
  Promise<undefined> write(FileSystemWriteChunkType data);
  Promise<undefined> seek(unsigned long long position);
  Promise<undefined> truncate(unsigned long long size);
};

FileSystemWritableFileStream 객체는 연관된 [[file]] ( 파일 항목)을 가지고 있습니다.

FileSystemWritableFileStream 객체는 연관된 [[buffer]] ( 바이트 시퀀스)을 가지고 있습니다. 이는 초기에는 비어 있습니다.

참고: 이 버퍼는 임의로 커질 수 있으므로, 구현체가 이를 메모리에 유지하지 않고 대신 임시 파일을 사용하는 것이 예상됩니다. [[buffer]]에 대한 모든 접근은 프라미스를 반환하는 메서드와 알고리즘에서 이루어지며, 동기 작업처럼 보이지만 구현체는 이를 비동기로 구현할 수 있습니다.

FileSystemWritableFileStream 객체는 연관된 [[seekOffset]] (숫자)을 가지고 있습니다. 이는 초기 값으로 0입니다.

FileSystemWritableFileStream 객체는 추가적인 편의 메서드를 포함한 WritableStream 객체로, 디스크의 단일 파일에서 동작합니다.

생성 시, 하위 싱크가 생성되며 스트림은 사용 가능해집니다. 스트림에서 실행되는 모든 작업은 큐에 추가될 수 있으며, 프로듀서는 역압에 응답할 수 있습니다.

하위 싱크의 write 메서드, 그리고 WritableStreamDefaultWriter의 write() 메서드는 바이트와 같은 데이터 또는 WriteParams 를 입력값으로 받을 수 있습니다.

FileSystemWritableFileStream 객체는 파일의 상단에서 바이트 오프셋 0으로 초기화된 파일 위치 커서를 가지고 있습니다. write() 를 사용하거나 WritableStreamDefaultWriter의 write() 메서드를 통해 WritableStream 기능을 사용할 때, 이 위치는 스트림 객체를 통해 기록된 바이트 수에 따라 진행됩니다.

마찬가지로, ReadableStreamFileSystemWritableFileStream 객체로 파이프할 때, 이 위치는 스트림을 통과한 바이트 수에 따라 업데이트됩니다.

getWriter()WritableStreamDefaultWriter 인스턴스를 반환합니다.

새로운 FileSystemWritableFileStream 생성파일 항목 fileRealm realm을 입력으로 받습니다:
  1. stream새로운 FileSystemWritableFileStream 으로 realm에 설정합니다.

  2. stream[[file]]file로 설정합니다.

  3. writeAlgorithmchunk 인수를 받아들이고 write a chunk 알고리즘을 streamchunk로 실행한 결과를 반환하는 알고리즘으로 설정합니다.

  4. closeAlgorithm을 다음 단계로 설정합니다:

    1. closeResult새로운 프라미스로 설정합니다.

    2. 다음 단계를 큐에 추가하여, 파일 시스템 큐에 실행합니다:

      1. accessResult를 "readwrite"를 입력으로 하여 file쿼리 액세스를 실행한 결과로 설정합니다.

      2. file관련 전역 객체에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:

        1. 만약 accessResult권한 상태가 "granted"가 아니라면, accessResult오류 이름으로 closeResult거부하고 이 단계를 중단합니다.

        2. 구현 정의된 악성코드 스캔 및 안전 브라우징 검사를 실행합니다. 이러한 검사가 실패하면, closeResult를 "AbortError" DOMException으로 거부하고 이 단계를 중단합니다.

        3. stream[[file]]바이너리 데이터stream[[buffer]]로 설정합니다. 예외가 발생하면, closeResult를 해당 예외로 거부하고 이 단계를 중단합니다.

          참고: 이는 디스크에 기록 중인 파일의 내용을 원자적으로 업데이트할 것으로 예상됩니다.

        4. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

          1. stream[[file]]에 대한 잠금 해제를 실행합니다.

          2. file관련 전역 객체에서 저장 작업을 큐에 추가하여, closeResultundefined해결합니다.

    3. closeResult를 반환합니다.

  5. abortAlgorithm을 다음 단계로 설정합니다:

    1. 이 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

      1. stream[[file]]에 대한 잠금 해제를 실행합니다.

  6. highWaterMark를 1로 설정합니다.

  7. sizeAlgorithm1을 반환하는 알고리즘으로 설정합니다.

  8. stream을 다음 값으로 설정합니다: writeAlgorithmwriteAlgorithm으로, closeAlgorithmcloseAlgorithm으로, abortAlgorithmabortAlgorithm으로, highWaterMarkhighWaterMark으로, 그리고 sizeAlgorithmsizeAlgorithm으로 설정합니다.

  9. stream을 반환합니다.

청크 쓰기 알고리즘은, FileSystemWritableFileStream streamchunk을 받아 다음 단계를 실행합니다:
  1. input변환하여 chunkFileSystemWriteChunkType으로 설정합니다. 변환 중 예외가 발생하면, 해당 예외로 거부된 프라미스를 반환합니다.

  2. p새로운 프라미스로 설정합니다.

  3. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. accessResultstream[[file]]쿼리 액세스를 "readwrite"로 실행한 결과로 설정합니다.

    2. 저장 작업을 큐에 추가하여 stream관련 전역 객체에서 다음 단계를 실행합니다:

      1. 만약 accessResult권한 상태가 "granted"가 아니라면, accessResult오류 이름으로 p거부하고 이 단계를 중단합니다.

      2. commandinput["type"] 로 설정합니다. 단, input딕셔너리가 아닌 경우, "write"로 설정합니다.

      3. 만약 command가 "write"라면:

        1. 만약 inputundefined이거나 input딕셔너리이고 input["data"] 가 존재하지 않는다면, pTypeError거부하고 이 단계를 중단합니다.

        2. datainput["data"] 로 설정합니다. 단, input딕셔너리가 아닌 경우, input으로 설정합니다.

        3. writePositionstream[[seekOffset]]로 설정합니다.

        4. 만약 input딕셔너리이고 input["position"] 존재한다면, writePositioninput["position"]로 설정합니다.

        5. oldSizestream[[buffer]]길이로 설정합니다.

        6. 만약 dataBufferSource라면, dataBytes복사본으로 설정합니다.

        7. 그 외, 만약 dataBlob이라면:

          1. dataBytes읽기 작업을 수행한 결과로 설정합니다. 예외가 발생하면, p를 해당 예외로 거부하고 이 단계를 중단합니다.

        8. 그 외:

          1. 단언: dataUSVString입니다.

          2. dataBytesUTF-8로 인코딩한 결과로 설정합니다.

        9. 만약 writePositionoldSize보다 크다면, writePosition - oldSize 만큼의 0x00 (NUL) 바이트를 stream[[buffer]] 끝에 추가합니다.

          참고: 구현체는 건너뛴 파일 내용이 실제로 NUL 바이트로 채워진 것처럼 동작해야 합니다. 이것이 실제로 디스크에 작성되어 공간을 차지해야 한다는 의미는 아닙니다. 대부분의 파일 시스템은 이러한 NUL 바이트가 실제 디스크 공간을 차지하지 않는 희소 파일을 지원합니다.

        10. head바이트 시퀀스로 설정하며, stream[[buffer]]의 처음 writePosition 바이트를 포함합니다.

        11. tail를 빈 바이트 시퀀스로 설정합니다.

        12. 만약 writePosition + data길이oldSize보다 작다면:

          1. tail바이트 시퀀스로 설정하며, stream[[buffer]]의 마지막 oldSize - (writePosition + data길이) 바이트를 포함합니다.

        13. stream[[buffer]]head, data, tail의 연결로 설정합니다.

        14. 만약 이전 단계에서 stream[[buffer]]를 수정하는 작업이 저장소 할당량을 초과하여 실패한 경우, p를 "QuotaExceededError" DOMException거부하고 이 단계를 중단하며, stream[[buffer]]는 수정하지 않습니다.

          참고: 저장소 할당량버킷 파일 시스템에 저장된 파일에만 적용됩니다. 그러나 이 작업은 여전히 다른 파일에서도 실패할 수 있습니다. 예를 들어, 쓰기를 시도하는 디스크의 공간이 부족한 경우입니다.

        15. stream[[seekOffset]]writePosition + data길이로 설정합니다.

        16. Resolve p.

      4. 그 외, 만약 command가 "seek"라면:

        1. 단언: chunk딕셔너리입니다.

        2. 만약 chunk["position"] 가 존재하지 않는다면, pTypeError거부하고 이 단계를 중단합니다.

        3. stream[[seekOffset]]chunk["position"]로 설정합니다.

        4. Resolve p.

      5. 그 외, 만약 command가 "truncate"라면:

        1. 단언: chunk딕셔너리입니다.

        2. 만약 chunk["size"] 가 존재하지 않는다면, pTypeError거부하고 이 단계를 중단합니다.

        3. newSizechunk["size"]로 설정합니다.

        4. oldSizestream[[buffer]]길이로 설정합니다.

        5. 만약 newSizeoldSize보다 크다면:

          1. stream[[buffer]]stream[[buffer]]newSize - oldSize 만큼의 0x00 바이트를 포함하는 바이트 시퀀스를 연결하여 설정합니다.

          2. 만약 이전 단계의 작업이 저장소 할당량 초과로 인해 실패한 경우, p를 "QuotaExceededError" DOMException거부하고 이 단계를 중단하며, stream[[buffer]]는 수정하지 않습니다.

            참고: 저장소 할당량버킷 파일 시스템에 저장된 파일에만 적용됩니다. 그러나 이 작업은 여전히 다른 파일에서도 실패할 수 있습니다. 예를 들어, 쓰기를 시도하는 디스크의 공간이 부족한 경우입니다.

        6. 그 외, 만약 newSizeoldSize보다 작다면:

          1. stream[[buffer]]stream[[buffer]]의 처음 newSize 바이트를 포함하는 바이트 시퀀스로 설정합니다.

        7. 만약 stream[[seekOffset]]newSize보다 크다면, stream[[seekOffset]]newSize로 설정합니다.

        8. Resolve p.

  4. p를 반환합니다.

2.5.1. write() 메서드

await stream . write(data)
await stream . write({ type: "write", data: data })

stream과 연결된 파일의 현재 커서 오프셋에 data의 내용을 기록합니다.

스트림이 닫히기 전까지 실제 디스크에 파일로 기록되지 않습니다. 변경 사항은 일반적으로 임시 파일에 기록됩니다.

await stream . write({ type: "write", position: position, data: data })

stream과 연결된 파일의 상단에서 position 바이트 떨어진 위치에 data의 내용을 기록합니다. 또한, 기록된 데이터의 끝으로 현재 파일 커서 오프셋을 업데이트합니다.

스트림이 닫히기 전까지 실제 디스크에 파일로 기록되지 않습니다. 변경 사항은 일반적으로 임시 파일에 기록됩니다.

await stream . write({ type: "seek", position: position })

파일 상단에서 position 바이트 떨어진 위치로 현재 파일 커서 오프셋을 업데이트합니다.

await stream . write({ type: "truncate", size: size })

stream과 연결된 파일의 크기를 size 바이트 길이로 조정합니다. size가 현재 파일 크기보다 크면 파일이 NUL 바이트로 채워지고, 작으면 파일이 잘립니다.

파일 커서는 truncate가 호출될 때 업데이트됩니다. 커서가 size보다 작으면 변경되지 않고, 커서가 size보다 크면 size로 설정되어 이후 기록 작업에서 오류가 발생하지 않도록 보장합니다.

스트림이 닫히기 전까지 실제 디스크에 파일로 기록되지 않습니다. 변경 사항은 일반적으로 임시 파일에 기록됩니다.

write(data) 메서드 단계는 다음과 같습니다:
  1. writerwriter 가져오기를 통해 this에서 가져온 결과로 설정합니다.

  2. result청크 쓰기writerdata를 사용하여 실행한 결과로 설정합니다.

  3. writer 해제를 실행합니다.

  4. result를 반환합니다.

2.5.2. seek() 메서드

await stream . seek(position)

파일 상단에서 position 바이트 떨어진 위치로 현재 파일 커서 오프셋을 업데이트합니다.

seek(position) 메서드 단계는 다음과 같습니다:
  1. writerwriter 가져오기를 통해 this에서 가져온 결과로 설정합니다.

  2. result청크 쓰기writer와 «[ "type" → "seek", "position" → position ]»를 사용하여 실행한 결과로 설정합니다.

  3. writer 해제를 실행합니다.

  4. result를 반환합니다.

2.5.3. truncate() 메서드

await stream . truncate(size)

stream과 연결된 파일의 크기를 size 바이트 길이로 조정합니다. size가 현재 파일 크기보다 크면 파일이 NUL 바이트로 채워지고, 작으면 파일이 잘립니다.

truncate가 호출될 때 파일 커서가 업데이트됩니다. 커서가 size보다 작으면 변경되지 않고, 커서가 size보다 크면 size로 설정되어 이후 기록 작업에서 오류가 발생하지 않도록 보장합니다.

스트림이 닫히기 전까지 실제 디스크에 파일로 기록되지 않습니다. 변경 사항은 일반적으로 임시 파일에 기록됩니다.

truncate(size) 메서드 단계는 다음과 같습니다:
  1. writerwriter 가져오기를 통해 this에서 가져온 결과로 설정합니다.

  2. result청크 쓰기writer와 «[ "type" → "truncate", "size" → size ]»를 사용하여 실행한 결과로 설정합니다.

  3. writer 해제를 실행합니다.

  4. result를 반환합니다.

2.6. FileSystemSyncAccessHandle 인터페이스

dictionary FileSystemReadWriteOptions {
  [EnforceRange] unsigned long long at;
};

[Exposed=DedicatedWorker, SecureContext]
interface FileSystemSyncAccessHandle {
  unsigned long long read(AllowSharedBufferSource buffer,
                          optional FileSystemReadWriteOptions options = {});
  unsigned long long write(AllowSharedBufferSource buffer,
                           optional FileSystemReadWriteOptions options = {});

  undefined truncate([EnforceRange] unsigned long long newSize);
  unsigned long long getSize();
  undefined flush();
  undefined close();
};

FileSystemSyncAccessHandle 객체는 연관된 [[file]] (파일 항목)을 가지고 있습니다.

FileSystemSyncAccessHandle 객체는 "open" 또는 "closed" 중 하나의 값을 가질 수 있는 연관된 [[state]]를 가지고 있습니다.

FileSystemSyncAccessHandle 객체는 단일 파일에서 읽기/쓰기, 크기 확인 및 변경을 수행할 수 있는 객체입니다.

FileSystemSyncAccessHandle 객체는 동기 메서드를 제공합니다. 이는 WebAssembly와 같이 비동기 작업에 높은 오버헤드가 수반되는 컨텍스트에서 높은 성능을 제공합니다.

FileSystemSyncAccessHandle 객체는 파일 상단에서 바이트 오프셋 0으로 초기화된 파일 위치 커서를 가지고 있습니다.

새로운 FileSystemSyncAccessHandle 생성파일 항목 fileRealm realm을 입력으로 받습니다:
  1. handle새로운 FileSystemSyncAccessHandle 으로 realm에 설정합니다.

  2. handle[[file]]file로 설정합니다.

  3. handle[[state]]를 "open"으로 설정합니다.

  4. handle을 반환합니다.

2.6.1. read() 메서드

handle . read(buffer)
handle . read(buffer, { at })

handle과 연결된 파일의 내용을 buffer에 읽어옵니다. 선택적으로 주어진 오프셋에서 읽습니다.

read() 가 호출되면 파일 커서는 마지막으로 읽은 바이트 다음 바이트를 가리키도록 업데이트됩니다.

외부에서 수정된 파일을 읽을 때 Access Handle이 어떻게 반응해야 하는지 명시하세요. [Issue #35]

read(buffer, FileSystemReadWriteOptions: options) 메서드 단계는 다음과 같습니다:
  1. 만약 this[[state]]가 "closed"라면, "InvalidStateError" DOMExceptionthrow합니다.

  2. bufferSizebuffer바이트 길이로 설정합니다.

  3. fileContentsthis[[file]]바이너리 데이터로 설정합니다.

  4. fileSizefileContents길이로 설정합니다.

  5. readStartoptions["at"] 로 설정합니다. 단, options["at"] 가 존재하지 않는다면, this파일 위치 커서로 설정합니다.

  6. 만약 기본 파일 시스템이 readStart 파일 오프셋에서 읽기를 지원하지 않는다면, throw TypeError.

  7. 만약 readStartfileSize보다 크다면:

    1. this파일 위치 커서fileSize로 설정합니다.

    2. 0을 반환합니다.

  8. readEndreadStart + (bufferSize − 1)로 설정합니다.

  9. 만약 readEndfileSize보다 크다면, readEndfileSize로 설정합니다.

  10. bytesfileContentsreadStart에서 readEnd까지의 바이트를 포함하는 바이트 시퀀스로 설정합니다.

  11. resultbytes길이로 설정합니다.

  12. 만약 이전 단계에서 fileContents에서 읽기 작업이 실패했다면:

    1. 부분적으로 읽은 바이트가 있고 bytes에 읽힌 바이트 수를 아는 경우, result를 읽은 바이트 수로 설정합니다.

    2. 그 외에는 result를 0으로 설정합니다.

  13. arrayBufferbuffer기본 버퍼로 설정합니다.

  14. Write bytesarrayBuffer에 씁니다.

  15. this파일 위치 커서readStart + result로 설정합니다.

  16. result를 반환합니다.

2.6.2. write() 메서드

handle . write(buffer)
handle . write(buffer, { at })

handle과 연결된 파일에 buffer의 내용을 기록합니다. 선택적으로 주어진 오프셋에서 기록하며, 기록된 바이트 수를 반환합니다. 반환되는 기록된 바이트 수를 확인하면 호출자가 오류와 부분 기록을 감지하고 처리할 수 있습니다.

write() 가 호출되면 파일 커서는 마지막으로 기록된 바이트 다음 바이트를 가리키도록 업데이트됩니다.

write(buffer, FileSystemReadWriteOptions: options) 메서드 단계는 다음과 같습니다:
  1. 만약 this[[state]]가 "closed"라면, "InvalidStateError" DOMExceptionthrow합니다.

  2. writePositionoptions["at"] 로 설정합니다. 단, options["at"] 가 존재하지 않는다면, this파일 위치 커서로 설정합니다.

  3. 만약 기본 파일 시스템이 writePosition 파일 오프셋에서 쓰기를 지원하지 않는다면, throw TypeError.

  4. fileContentsthis[[file]]바이너리 데이터의 복사본으로 설정합니다.

  5. oldSizefileContents길이로 설정합니다.

  6. bufferSizebuffer바이트 길이로 설정합니다.

  7. 만약 writePositionoldSize보다 크다면, writePositionoldSize 0x00 (NUL) 바이트를 fileContents 끝에 추가합니다.

    참고: 구현체는 건너뛴 파일 내용이 실제로 NUL 바이트로 채워진 것처럼 동작해야 합니다. 이것이 실제로 디스크에 작성되어 공간을 차지해야 한다는 의미는 아닙니다. 대부분의 파일 시스템은 이러한 NUL 바이트가 실제 디스크 공간을 차지하지 않는 희소 파일을 지원합니다.

  8. headfileContents의 처음 writePosition 바이트를 포함하는 바이트 시퀀스로 설정합니다.

  9. tail를 빈 바이트 시퀀스로 설정합니다.

  10. 만약 writePosition + bufferSizeoldSize보다 작다면:

    1. tailfileContents의 마지막 oldSize − (writePosition + bufferSize) 바이트를 포함하는 바이트 시퀀스로 설정합니다.

  11. newSizehead길이 + bufferSize + tail길이로 설정합니다.

  12. 만약 newSizeoldSize가 사용 가능한 저장소 할당량을 초과한다면, throw "QuotaExceededError" DOMException.

  13. this[[file]]바이너리 데이터head, buffer의 내용, tail의 연결로 설정합니다.

    참고: 버퍼의 내용을 접근하는 메커니즘은 의도적으로 모호하게 설정되었습니다. 구현체는 성능을 중점으로 하여 호스트 운영 체제에 직접 쓰기 호출을 실행하는 방식을 선택할 가능성이 높습니다 (버퍼의 복사본을 생성하는 대신), 이는 쓰기 순서와 부분 쓰기의 결과에 대한 자세한 명세를 방해합니다.

  14. 만약 이전 단계를 통해 this[[file]]바이너리 데이터를 수정하는 작업이 실패했다면:

    1. 부분적으로 기록된 바이트가 있고 buffer에서 기록된 바이트 수를 아는 경우:

      1. bytesWrittenbuffer에서 기록된 바이트 수로 설정합니다.

      2. this파일 위치 커서writePosition + bytesWritten으로 설정합니다.

      3. bytesWritten을 반환합니다.

    2. 그 외에는 throw "InvalidStateError" DOMException.

  15. this파일 위치 커서writePosition + bufferSize로 설정합니다.

  16. bufferSize를 반환합니다.

2.6.3. truncate() 메서드

handle . truncate(newSize)

handle과 연결된 파일의 크기를 newSize 바이트 길이로 조정합니다. newSize가 현재 파일 크기보다 크면 파일이 NUL 바이트로 채워지고, 작으면 파일이 잘립니다.

truncate가 호출될 때 파일 커서가 업데이트됩니다. 커서가 newSize보다 작으면 변경되지 않고, 커서가 newSize보다 크면 newSize로 설정됩니다.

truncate(newSize) 메서드 단계는 다음과 같습니다:
  1. 만약 this[[state]]가 "closed"라면, "InvalidStateError" DOMExceptionthrow합니다.

  2. fileContentsthis[[file]]바이너리 데이터의 복사본으로 설정합니다.

  3. oldSize길이로 설정하고 this[[file]]바이너리 데이터로 설정합니다.

  4. 만약 기본 파일 시스템이 파일 크기를 newSize로 설정하는 것을 지원하지 않는다면, throw TypeError.

  5. 만약 newSizeoldSize보다 크다면:

    1. 만약 newSizeoldSize가 사용 가능한 저장소 할당량을 초과한다면, throw "QuotaExceededError" DOMException.

    2. this[[file]]fileContentsnewSizeoldSize 0x00 바이트를 포함하는 바이트 시퀀스로 연결하여 설정합니다.

    3. 만약 이전 단계에서 this[[file]]바이너리 데이터를 수정하는 작업이 실패했다면, "InvalidStateError" DOMExceptionthrow합니다.

  6. 그 외, 만약 newSizeoldSize보다 작다면:

    1. this[[file]]fileContents의 처음 newSize 바이트를 포함하는 바이트 시퀀스로 설정합니다.

    2. 만약 이전 단계에서 this[[file]]바이너리 데이터를 수정하는 작업이 실패했다면, "InvalidStateError" DOMExceptionthrow합니다.

  7. 만약 this파일 위치 커서newSize보다 크다면, 파일 위치 커서newSize로 설정합니다.

2.6.4. getSize() 메서드

handle . getSize()

handle과 연결된 파일의 크기를 바이트 단위로 반환합니다.

getSize() 메서드 단계는 다음과 같습니다:
  1. 만약 this[[state]]가 "closed"라면, "InvalidStateError" DOMExceptionthrow합니다.

  2. this[[file]]바이너리 데이터길이를 반환합니다.

2.6.5. flush() 메서드

handle . flush()

handle과 연결된 파일의 내용이 write()를 통해 수행된 모든 수정 사항을 포함하도록 보장합니다.

flush() 메서드 단계는 다음과 같습니다:
  1. 만약 this[[state]]가 "closed"라면, "InvalidStateError" DOMExceptionthrow합니다.

  2. 파일 내용의 모든 캐시된 수정 사항을 파일 시스템의 기본 저장 장치로 전송하려고 시도합니다.

    참고: 이는 플러싱(flushing)이라고도 알려져 있습니다. 일부 메모리 파일 시스템과 같이 "디스크"로 플러시할 필요가 없는 파일 시스템에서는 이 작업이 아무 작업도 수행하지 않을 수 있습니다.

2.6.6. close() 메서드

handle . close()

접근 핸들을 닫거나, 접근 핸들이 이미 닫혀 있는 경우 아무 작업도 수행하지 않습니다. 이는 해당 핸들에 대한 추가 작업을 비활성화하고 잠금을 해제합니다. handle과 연관된 [[file]]에 대해.

close() 메서드 단계는 다음과 같습니다:
  1. 만약 this[[state]]가 "closed"라면, 반환합니다.

  2. this[[state]]를 "closed"로 설정합니다.

  3. lockReleased를 false로 설정합니다.

  4. filethis[[file]]로 설정합니다.

  5. 다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:

    1. 잠금을 해제합니다. file에 대해.

    2. lockReleased를 true로 설정합니다.

  6. Pause하여 lockReleased가 true가 될 때까지 대기합니다.

참고: 이 메서드는 모든 파일 수정 사항이 기본 저장 장치에 즉시 반영될 것을 보장하지 않습니다. 이러한 보장이 필요한 경우 flush() 메서드를 먼저 호출하세요.

3. 버킷 파일 시스템 접근

버킷 파일 시스템저장소 엔드포인트이며, 식별자"fileSystem", 유형« "local" », 할당량은 null입니다.

저장소 엔드포인트는 [storage] 자체에서 정의되어야 하며, 여기에서 정의되지 않아야 합니다. 따라서 이를 해당 표에 병합하세요.

참고: 사용자 에이전트는 일반적으로 버킷 파일 시스템의 내용을 디스크에 저장하여 구현하지만, 이는 사용자가 쉽게 접근할 수 있도록 의도된 것은 아닙니다. 마찬가지로, 버킷 파일 시스템의 하위 항목 이름과 일치하는 파일이나 디렉토리가 존재할 것이라는 기대도 없습니다.

[SecureContext]
partial interface StorageManager {
  Promise<FileSystemDirectoryHandle> getDirectory();
};
directoryHandle = await navigator . storage . getDirectory()

버킷 파일 시스템의 루트 디렉토리를 반환합니다.

getDirectory() 메서드 단계는 다음과 같습니다:
  1. environment현재 설정 객체로 설정합니다.

  2. mapenvironment"fileSystem"을 사용하여 로컬 저장소 병 맵 획득을 실행한 결과로 설정합니다. 실패를 반환하면, "SecurityError" DOMException으로 거부된 프라미스를 반환합니다.

  3. 만약 map["root"]이 존재하지 않는다면:

    1. dir디렉토리 항목으로 설정합니다. 이 항목의 쿼리 액세스요청 액세스 알고리즘은 항상 "granted" 파일 시스템 액세스 결과를 반환하며, 오류 이름은 빈 문자열로 설정합니다.

    2. dir이름을 빈 문자열로 설정합니다.

    3. dir하위 항목을 빈 집합으로 설정합니다.

    4. map["root"]을 dir로 설정합니다.

  4. root구현 정의 불투명한 문자열로 설정합니다.

  5. path를 « 빈 문자열 »로 설정합니다.

  6. handle새로운 FileSystemDirectoryHandle 생성을 실행한 결과로 설정합니다. rootpath현재 Realm에서 사용하여.

    참고: root는 관련 식별 정보(예: 저장소 버킷)를 포함할 수 있습니다.

  7. 단언: 항목 위치 찾기handle로케이터 를 사용하여 실행하면 map["root"]와 동일한 디렉토리 항목을 반환합니다.

  8. 프라미스가 해결된 handle을 반환합니다.

감사의 글

진심으로 감사드립니다: Alex Danilo, Anne van Kesteren, Anoesj Sadraee, Austin Sullivan, Chase Phillips, Daseul Lee, Dru Knox, Edgar Chen, Emanuel Krivoy, Hazim Mohamed, Ingvar Stepanyan, Jari Jalkanen, Joshua Bell, Kagami Sascha Rosylight, Marcos Cáceres, Martin Thomson, Olivier Yiptong, Philip Jägenstedt, Randell Jesup, Richard Stotz, Ruth John, Sid Vishnoi, Sihui Liu, Stefan Sauer, Thomas Steiner, Victor Costan, and Youenn Fablet 여러분, 최고입니다!

이 표준은 Marijn Kruisselbrink (Google, mek@chromium.org)가 작성했습니다.

지적 재산권

이 현행 표준은 W3C WICG의 File System Access에서 복사한 자료를 포함하고 있으며, W3C 소프트웨어 및 문서 라이선스 하에 제공됩니다.

Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). 이 작업은 Creative Commons Attribution 4.0 International License 하에 라이선스가 부여됩니다. 소스 코드에 통합된 일부는 BSD 3-Clause License 하에 라이선스가 부여됩니다.

이것이 현행 표준입니다. 특허 검토 버전에 관심이 있는 분들은 현행 표준 검토 초안을 참고하세요.

색인

이 명세서에서 정의된 용어

참조에 의해 정의된 용어

참조

규범 참조

[ECMASCRIPT]
ECMAScript 언어 명세. URL: https://tc39.es/ecma262/multipage/
[ENCODING]
Anne van Kesteren. 인코딩 표준. 현행 표준. URL: https://encoding.spec.whatwg.org/
[FILE-API]
Marijn Kruisselbrink. 파일 API. URL: https://w3c.github.io/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML 표준. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 표준. 현행 표준. URL: https://infra.spec.whatwg.org/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. 권한. URL: https://w3c.github.io/permissions/
[PERMISSIONS-REQUEST]
권한 요청. 커뮤니티 그룹 초안 보고서. URL: https://wicg.github.io/permissions-request/
[STORAGE]
Anne van Kesteren. 저장소 표준. 현행 표준. URL: https://storage.spec.whatwg.org/
[STREAMS]
Adam Rice; et al. 스트림 표준. 현행 표준. URL: https://streams.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. 웹 IDL 표준. 현행 표준. URL: https://webidl.spec.whatwg.org/

IDL 색인

enum FileSystemHandleKind {
  "file",
  "directory",
};

[Exposed=(Window,Worker), SecureContext, Serializable]
interface FileSystemHandle {
  readonly attribute FileSystemHandleKind kind;
  readonly attribute USVString name;

  Promise<boolean> isSameEntry(FileSystemHandle other);
};

dictionary FileSystemCreateWritableOptions {
  boolean keepExistingData = false;
};

[Exposed=(Window,Worker), SecureContext, Serializable]
interface FileSystemFileHandle : FileSystemHandle {
  Promise<File> getFile();
  Promise<FileSystemWritableFileStream> createWritable(optional FileSystemCreateWritableOptions options = {});
  [Exposed=DedicatedWorker]
  Promise<FileSystemSyncAccessHandle> createSyncAccessHandle();
};

dictionary FileSystemGetFileOptions {
  boolean create = false;
};

dictionary FileSystemGetDirectoryOptions {
  boolean create = false;
};

dictionary FileSystemRemoveOptions {
  boolean recursive = false;
};

[Exposed=(Window,Worker), SecureContext, Serializable]
interface FileSystemDirectoryHandle : FileSystemHandle {
  async_iterable<USVString, FileSystemHandle>;

  Promise<FileSystemFileHandle> getFileHandle(USVString name, optional FileSystemGetFileOptions options = {});
  Promise<FileSystemDirectoryHandle> getDirectoryHandle(USVString name, optional FileSystemGetDirectoryOptions options = {});

  Promise<undefined> removeEntry(USVString name, optional FileSystemRemoveOptions options = {});

  Promise<sequence<USVString>?> resolve(FileSystemHandle possibleDescendant);
};

enum WriteCommandType {
  "write",
  "seek",
  "truncate",
};

dictionary WriteParams {
  required WriteCommandType type;
  unsigned long long? size;
  unsigned long long? position;
  (BufferSource or Blob or USVString)? data;
};

typedef (BufferSource or Blob or USVString or WriteParams) FileSystemWriteChunkType;

[Exposed=(Window,Worker), SecureContext]
interface FileSystemWritableFileStream : WritableStream {
  Promise<undefined> write(FileSystemWriteChunkType data);
  Promise<undefined> seek(unsigned long long position);
  Promise<undefined> truncate(unsigned long long size);
};

dictionary FileSystemReadWriteOptions {
  [EnforceRange] unsigned long long at;
};

[Exposed=DedicatedWorker, SecureContext]
interface FileSystemSyncAccessHandle {
  unsigned long long read(AllowSharedBufferSource buffer,
                          optional FileSystemReadWriteOptions options = {});
  unsigned long long write(AllowSharedBufferSource buffer,
                           optional FileSystemReadWriteOptions options = {});

  undefined truncate([EnforceRange] unsigned long long newSize);
  unsigned long long getSize();
  undefined flush();
  undefined close();
};


[SecureContext]
partial interface StorageManager {
  Promise<FileSystemDirectoryHandle> getDirectory();
};