1. 소개
이 섹션은 비규범적입니다.
이 문서는 파일 시스템 API를 위한 기본 인프라를 정의합니다. 또한, 사용자가 액세스를 요청하기 전에 웹사이트가 파일 시스템 디렉토리에 액세스할 수 있도록 하는 API를 정의합니다. 이는
웹사이트가 사용자가 저장 위치를 선택하기 전에 데이터를 디스크에 저장하려는 경우 완전히 다른 저장 메커니즘과 API를 사용하도록 강제하지 않고도 이를 가능하게 합니다. 이의 진입점은 navigator.storage.getDirectory()
메서드입니다.
2. 파일 및 디렉토리
2.1. 개념
파일 시스템 항목은 파일 항목 또는 디렉토리 항목 중 하나입니다.
각 파일 시스템 항목은 연관된
쿼리 액세스
알고리즘을 가지며, 이는 "read
" 또는 "readwrite
" mode를 받아 파일 시스템 액세스 결과를 반환합니다.
별도로 명시되지 않은 경우, 이는 파일 시스템 액세스 결과를 반환하며,
권한 상태가 "denied
"
이고 오류 이름이 빈 문자열인 경우입니다.
각 파일 시스템 항목은 연관된
요청 액세스
알고리즘을 가지며, 이는 "read
" 또는 "readwrite
" mode를 받아 파일 시스템 액세스 결과를 반환합니다.
별도로 명시되지 않은 경우, 이는 파일 시스템 액세스 결과를 반환하며,
권한 상태가 "denied
"
이고 오류 이름이 빈 문자열인 경우입니다.
파일 시스템 액세스 결과는 구조체로 파일 시스템에 대한 쿼리 또는 요청 결과를 캡슐화합니다. 이는 다음과 같은 항목을 포함합니다:
- 권한 상태
- 오류 이름
-
문자열로, 만약 권한 상태가 "
granted
" 일 경우 빈 문자열이어야 합니다. 그렇지 않은 경우, 이름으로DOMException
이름 테이블에 나열된 항목이어야 합니다. 대부분의 경우, 권한 상태가 "granted
" 가 아닌 경우, 이는 "NotAllowedError
"여야 합니다.
종속 명세는 이 API를 강력한 기능으로 간주할 수 있습니다. 그러나, 다른 강력한 기능과 달리 권한 요청 알고리즘이 예외를 발생시킬 수 있는 경우, 파일 시스템 항목의 쿼리 액세스와 요청 액세스 알고리즘은 병렬로 파일 시스템 큐에서 실행되어야 하며, 따라서 예외를 발생시킬 수 없습니다. 대신, 호출자가 적절히 저장 작업을 큐에 추가하여 거부하도록 해야 하며, 이러한 알고리즘이 빈 문자열이 아닌 오류 이름을 반환할 경우 이를 처리해야 합니다.
참고: 이 명세만 구현하고 종속 명세를 구현하지 않는 경우 파일 시스템 항목의 쿼리 액세스와 요청 액세스를 구현할 필요가 없습니다.
FileSystemHandle과 관련된 액세스 확인 알고리즘을 만들 필요가 있습니다. [Issue #101]
각 파일 시스템 항목은 연관된 이름을 가집니다 (문자열).
유효한 파일 이름은 문자열로, 빈 문자열이 아니고 "." 또는 ".."와 같지 않으며, '/' 또는 기본 플랫폼에서 경로 구분자로 사용되는 다른 문자를 포함하지 않아야 합니다.
참고: 이는 Windows에서 이름에 '\'를 허용하지 않음을 의미하지만, 다른 운영 체제에서는 허용될 수 있습니다. 또한, 기본 파일 시스템은 이름에 대해 추가적인 제한을 가질 수 있으므로, 문자열이 단순히 유효한 파일 이름이라고 해서 해당 이름으로 파일이나 디렉토리를 생성할 수 있다는 보장은 없습니다.
이 API를 사용하여 결코 허용되지 않을 파일 이름에 대해 추가적인 규범적 제한을 고려해야 하며, 이를 기본 파일 시스템에 전적으로 맡기지 않아야 합니다.
파일 항목은 추가적으로
바이너리 데이터 (바이트 시퀀스), 수정 타임스탬프 (유닉스 에포크 이후 밀리초를 나타내는 숫자),
잠금 (문자열로 "open
", "taken-exclusive
" 또는
"taken-shared
" 중 하나일 수 있음),
그리고 공유 잠금 수 (주어진 시점에 취해진 공유 잠금의 수를 나타내는 숫자)로 구성됩니다.
사용자 에이전트는 파일 시스템 큐를 가지며, 이는 새 병렬 큐 시작의 결과입니다. 이 큐는 모든 파일 시스템 작업에 사용됩니다.
exclusive
" 또는
"shared
"로 설정합니다. 파일 항목
file에 대해:
-
lock을 file의 잠금으로 설정합니다.
-
count를 file의 공유 잠금 수로 설정합니다.
-
만약 value가 "
exclusive
"라면:-
만약 lock이 "
open
"이라면:-
잠금을 "
taken-exclusive
"로 설정합니다. -
"
success
"를 반환합니다.
-
-
-
만약 value가 "
shared
"라면:-
만약 lock이 "
open
"이라면:-
lock을 "
taken-shared
"로 설정합니다. -
count를 1로 설정합니다.
-
"
success
"를 반환합니다.
-
-
그 외에, 만약 lock이 "
taken-shared
"이라면:-
count를 1 증가시킵니다.
-
"
success
"를 반환합니다.
-
-
-
"
failure
"를 반환합니다.
참고: 이 단계는 파일 시스템 큐에서 실행되어야 합니다.
-
lock을 file의 연관된 잠금으로 설정합니다.
-
count를 file의 공유 잠금 수로 설정합니다.
-
만약 lock이 "
taken-shared
"이라면:-
count를 1 감소시킵니다.
-
만약 count가 0이라면, lock을 "
open
"으로 설정합니다.
-
-
그 외에는, lock을 "
open
"으로 설정합니다.
참고: 이 단계는 파일 시스템 큐에서 실행되어야 합니다.
참고: 잠금은 파일의 동시 수정 방지를 돕습니다. FileSystemWritableFileStream
은 공유 잠금이 필요하고, FileSystemSyncAccessHandle
은 배타적 잠금이 필요합니다.
디렉토리 항목은 추가적으로 집합으로 구성된 자식 항목을 포함하며, 이들은 파일 시스템 항목이 됩니다. 각 멤버는 파일 항목이거나 디렉토리 항목입니다.
파일 시스템 항목 entry는 최대 하나의 자식 항목 안에 포함되어야 하며, 해당 디렉토리 항목은 entry의 부모로 알려집니다. 파일 시스템 항목의 부모가 존재하지 않을 경우 null이 됩니다.
참고: 서로 다른 두 파일 시스템 항목이 디스크에서 동일한 파일이나 디렉토리를 나타낼 수 있으며, 이 경우 두 항목이 서로 다른 부모를 가질 수도 있고, 하나의 항목만 부모를 가질 수도 있습니다.
파일 시스템 항목은 (필수는 아니지만) 호스트 운영 체제의 로컬 파일 시스템에 의해 지원될 수 있으므로, 바이너리 데이터, 수정 타임스탬프, 그리고 자식 항목이 이 명세 외부의 응용 프로그램에 의해 수정될 가능성이 있습니다. 외부 변경 사항이 이 명세에서 정의된 데이터 구조에 반영되는 방식과, 이 명세에서 정의된 데이터 구조에 대한 변경 사항이 외부에 반영되는 방식은 개별 사용자 에이전트 구현에 맡겨집니다.
파일 시스템 항목 a는 동일한 항목으로 간주됩니다. 파일 시스템 항목 b가 a와 동일하거나, a와 b가 로컬 파일 시스템에서 동일한 파일 또는 디렉토리를 지원하는 경우입니다.
해결하려면 파일 시스템 로케이터 child를 디렉토리 로케이터 root에 상대적으로 설정합니다:
-
result를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
만약 child의 로케이터의 루트가 root의 로케이터의 루트와 다르다면, 해결 result를 null로 설정하고, 단계를 중지합니다.
-
만약 childPath가 동일한 경로라면 rootPath, 해결 result를 « »로 설정하고, 단계를 중지합니다.
-
만약 rootPath의 크기가 childPath의 크기보다 크다면, 해결 result를 null로 설정하고, 단계를 중지합니다.
-
각각의 index에 대해 rootPath의 인덱스를 반복합니다:
-
만약 rootPath.[[index]]가 childPath.[[index]]와 다르다면, 해결 result를 null로 설정하고, 단계를 중지합니다.
-
-
relativePath를 « »로 설정합니다.
-
각각의 index에 대해 범위를 반복합니다. rootPath의 크기에서 시작하여, rootPath의 크기까지 독점적으로 반복하며, 추가 childPath.[[index]]를 relativePath에 설정합니다.
-
해결 result를 relativePath로 설정합니다.
-
-
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의 경로와 동일한 경우입니다.
파일 시스템 경로는 하나 이상의 항목으로 이루어진 목록이며, 각각은 문자열입니다. 이는 디스크나 메모리의 실제 위치에 매핑된 가상 경로일 수도 있고, 로컬 파일 시스템의 경로와 직접적으로 대응하거나, 디스크에 있는 파일과 전혀 대응하지 않을 수도 있습니다. 해당 파일 시스템 항목의 실제 물리적 위치는 구현 정의입니다.
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]
-
만약 serialized.[[Origin]]이 value의 관련 설정 객체의 원점과 같은 원점이 아니라면, "
DataCloneError
"DOMException
을 발생시킵니다. -
value의 로케이터를 serialized.[[Locator]]로 설정합니다.
- handle .
kind
-
만약 handle이
FileSystemFileHandle
이라면 "file
"을 반환하고, handle이FileSystemDirectoryHandle
이라면 "directory
"를 반환합니다.이는 디렉토리 내용을 순회할 때 파일과 디렉토리를 구분하는 데 사용될 수 있습니다.
- handle .
name
kind
getter 단계는
this의 로케이터의
종류를 반환하는 것입니다.
name
getter 단계는
this의 로케이터의
경로의 마지막 항목 (a 문자열)을 반환하는
것입니다.
2.2.1.
isSameEntry()
메서드
- same = await handle1 .
isSameEntry
( handle2 ) -
handle1과 handle2가 동일한 파일 또는 디렉토리를 나타내는 경우 true를 반환합니다.
isSameEntry(other)
메서드 단계는 다음과 같습니다:
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
만들기는
파일 시스템 루트
root와 파일 시스템
경로 path,
그리고 Realm
realm을 입력으로 받습니다:
-
handle을 새로운
FileSystemFileHandle
로 realm에 설정합니다. -
handle의 로케이터를 파일 시스템 로케이터로 설정하며, 그 종류는 "
file
", 루트는 root, 그리고 경로는 path입니다. -
handle을 반환합니다.
FileSystemFileHandle
객체는 직렬화 가능한 객체입니다. 그 직렬화 단계와
역직렬화 단계는 FileSystemHandle
과
동일합니다.
2.3.1.
getFile()
메서드
getFile()
메서드 단계는 다음과 같습니다:
-
result를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
entry를 locator를 입력으로 받아 항목 찾기의 결과로 설정합니다.
-
accessResult를 "
read
"를 입력으로 하여 entry의 쿼리 액세스를 실행한 결과로 설정합니다. -
저장 작업을 큐에 추가하여 global에서 다음 단계를 실행합니다:
-
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, accessResult의 오류 이름으로 result를 거부하고 이 단계를 중단합니다. -
만약 entry가 null이라면, result를 "
NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
f를 새로운
File
로 설정합니다. -
f의 스냅샷 상태를 entry의 현재 상태로 설정합니다.
-
f의 기본 바이트 시퀀스를 entry의 바이너리 데이터의 복사본으로 설정합니다.
-
f의
lastModified
를 entry의 수정 타임스탬프로 설정합니다. -
f의
type
을 구현 정의된 값으로 설정하며, 이는 예를 들어 entry의 이름이나 파일 확장자를 기반으로 합니다.읽기 및 스냅샷 생성 동작은 [FILE-API] 명세에서 더 명확히 정의되어야 하며, 현재로서는 다소 모호합니다.
-
result를 f로 해결합니다.
-
-
-
result를 반환합니다.
2.3.2. createWritable()
메서드
- stream = await fileHandle .
createWritable()
- stream = await fileHandle .
createWritable
({keepExistingData
: true/false }) - stream = await fileHandle .
-
FileSystemWritableFileStream
을 반환하며, 이를 사용하여 파일에 기록할 수 있습니다. stream을 통해 수행한 변경 사항은 fileHandle의 로케이터로 위치를 확인할 수 있는 파일 항목에 스트림이 닫힐 때까지 반영되지 않습니다. 사용자는 부분 쓰기가 발생하지 않도록 보장하려고 시도합니다. 즉, 파일은 이전 내용이거나 스트림이 닫힐 때까지 stream을 통해 기록된 데이터를 포함합니다.이는 일반적으로 데이터를 임시 파일에 기록한 다음, 기록 가능한 파일 스트림이 닫힐 때 fileHandle의 로케이터로 위치를 확인할 수 있는 파일 항목을 임시 파일로 교체하는 방식으로 구현됩니다.
만약
keepExistingData
가 false이거나 지정되지 않은 경우, 임시 파일은 비어 있는 상태로 시작하며, 그렇지 않으면 기존 파일이 먼저 이 임시 파일로 복사됩니다.FileSystemWritableFileStream
을 생성하면 파일 항목에서 공유 잠금을 가져옵니다. 이는 스트림이 닫힐 때까지 해당 항목에 대해FileSystemSyncAccessHandles
의 생성을 방지합니다.
createWritable에 대한 "inPlace" 모드(변경 사항이 작성자에 기록되는 대로 실제 기본 파일에 기록되는 모드)를 구현하기 위한 논의는
WICG/file-system-access issue #67에서 확인할 수
있습니다.
이는 현재 Chrome에서 구현되지 않았습니다. 이를 구현하는 데에는 맬웨어 검사를 실행하려는 요구와
기존 대형 파일에 대해 웹사이트가 빠르게 변경을 수행할 수 있도록 하려는 요구를 결합하는 방법을 찾는 것이 장애물로 작용하고 있습니다.
버킷 파일
시스템의 파일은
FileSystemSyncAccessHandle
인터페이스를 통해 인플레이스 쓰기가 가능합니다.
createWritable(options)
메서드 단계는 다음과 같습니다:
-
result를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
entry를 locator를 입력으로 받아 항목 찾기의 결과로 설정합니다.
-
accessResult를 "
readwrite
"를 입력으로 하여 entry의 요청 액세스를 실행한 결과로 설정합니다. -
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, global에서 저장 작업을 큐에 추가하여 accessResult의 오류 이름으로 result를 거부하고 이 단계를 중단합니다. -
만약 entry가
null
이라면, global에서 저장 작업을 큐에 추가하여 result를 "NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
lockResult를 entry에 대해 "
shared
"를 입력으로 하여 잠금 가져오기의 결과로 설정합니다. -
global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:
-
만약 lockResult가 "
failure
"라면, result를 "NoModificationAllowedError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
stream을 entry에 대해 realm에서 새로운
FileSystemWritableFileStream
생성의 결과로 설정합니다. -
만약 options["
keepExistingData
"] 가 true라면:-
stream의 [[buffer]]를 entry의 바이너리 데이터의 복사본으로 설정합니다.
-
-
result를 stream으로 해결합니다.
-
-
-
result를 반환합니다.
2.3.3. createSyncAccessHandle()
메서드
- handle = await fileHandle .
createSyncAccessHandle
() -
FileSystemSyncAccessHandle
을 반환하며, 이를 사용하여 파일을 읽거나 쓸 수 있습니다. handle을 통해 수행한 변경 사항은 fileHandle의 로케이터로 위치를 확인할 수 있는 파일 항목에 즉시 반영될 수 있습니다. 이러한 변경 사항을 파일에 반영하려면 핸들을 플러시할 수 있습니다.FileSystemSyncAccessHandle
을 생성하면 fileHandle의 로케이터로 위치를 확인할 수 있는 파일 항목에 대해 배타적 잠금을 가져옵니다. 이로 인해 액세스 핸들이 닫힐 때까지 해당 항목에 대해 추가FileSystemSyncAccessHandles
또는FileSystemWritableFileStreams
생성이 방지됩니다.반환된
FileSystemSyncAccessHandle
은 동기 메서드를 제공합니다. 이는 비동기 작업에 높은 오버헤드가 있는 WebAssembly와 같은 컨텍스트에서 더 높은 성능을 제공합니다.현재 이 메서드는 fileHandle이 버킷 파일 시스템에 존재하는 경우에만 성공합니다.
createSyncAccessHandle()
메서드 단계는
다음과 같습니다:
-
result를 새로운 프라미스로 설정합니다.
-
isInABucketFileSystem을 this가 버킷 파일 시스템에 존재한다면 true로 설정하고, 그렇지 않으면 false로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
entry를 locator를 입력으로 받아 항목 찾기의 결과로 설정합니다.
-
accessResult를 "
readwrite
"를 입력으로 하여 entry의 요청 액세스를 실행한 결과로 설정합니다. -
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, global에서 저장 작업을 큐에 추가하여 accessResult의 오류 이름으로 result를 거부하고 이 단계를 중단합니다. -
만약 isInABucketFileSystem이 false라면, global에서 저장 작업을 큐에 추가하여 result를 "
InvalidStateError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
만약 entry가
null
이라면, global에서 저장 작업을 큐에 추가하여 result를 "NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
lockResult를 entry에 대해 "
exclusive
"를 입력으로 하여 잠금 가져오기의 결과로 설정합니다. -
global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:
-
만약 lockResult가 "
failure
"라면, result를 "NoModificationAllowedError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
handle을 entry에 대해 realm에서 새로운
FileSystemSyncAccessHandle
생성의 결과로 설정합니다. -
result를 handle으로 해결합니다.
-
-
-
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
생성은
파일 시스템 루트
root와 파일 시스템
경로 path,
그리고 Realm
realm을 입력으로 받습니다:
-
handle을 새로운
FileSystemDirectoryHandle
로 realm에 설정합니다. -
handle의 로케이터를 파일 시스템 로케이터로 설정하며, 그 종류는 "
directory
", 루트는 root, 그리고 경로는 path입니다. -
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()) {}
- for await (let [name, handle] of directoryHandle . entries()) {}
-
directoryHandle의 로케이터로 위치를 확인할 수 있는 디렉토리 항목을 부모로 가지는 모든 항목을 반복합니다. 반복이 진행되는 동안 생성되거나 삭제된 항목은 포함될 수도 있고 포함되지 않을 수도 있습니다. 어느 쪽이든 보장되지 않습니다.
향후 비동기 반복 선언에 재귀적 반복과 같은 지원을 추가하기 위해 매개변수를 추가할 수 있습니다. [Issue #15]
FileSystemDirectoryHandle
handle과 그 비동기 반복자 iterator에 대해 다음과 같습니다:
-
iterator의 이전 결과를 빈 집합으로 설정합니다.
FileSystemDirectoryHandle
handle과 그 비동기 반복자 iterator에 대해
다음 반복 결과 얻기는 다음과 같습니다:
-
promise를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
accessResult를 "
read
"를 입력으로 하여 directory의 쿼리 액세스를 실행한 결과로 설정합니다. -
handle의 관련 전역 객체에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:
-
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, accessResult의 오류 이름으로 promise를 거부하고 이 단계를 중단합니다. -
만약 directory가
null
이라면, result를 "NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
child를 directory의 자식 항목 중 하나로 설정하며, child의 이름이 iterator의 이전 결과에 포함되지 않은 항목이어야 합니다. 그러한 항목이 없으면
null
로 설정합니다.참고: 이는 반복 순서에 대해 의도적으로 모호하게 정의되어 있습니다. 서로 다른 플랫폼과 파일 시스템은 반복 순서에 대해 서로 다른 보장을 제공하며, 모든 플랫폼에서 효율적으로 구현할 수 있도록 하기 위해 정확한 순서에 대한 보장은 제공되지 않습니다.
-
만약 child가
null
이라면, promise를undefined
로 해결하고 이 단계를 중단합니다. -
만약 child가 파일 항목이라면:
-
result를 handle의 로케이터와 child의 이름, 그리고 handle의 관련 Realm을 사용하여 자식
FileSystemFileHandle
생성의 결과로 설정합니다.
-
-
그 외에는:
-
result를 handle의 로케이터와 child의 이름, 그리고 handle의 관련 Realm을 사용하여 자식
FileSystemDirectoryHandle
생성의 결과로 설정합니다.
-
-
-
promise를 반환합니다.
2.4.2. getFileHandle()
메서드
- fileHandle = await directoryHandle .
getFileHandle
(name)- fileHandle = await directoryHandle .
getFileHandle
(name, {create
: false }) - fileHandle = await directoryHandle .
-
directoryHandle의 로케이터로 위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 파일에 대한 핸들을 반환합니다. 해당 파일이 존재하지 않는 경우, 이 메서드는 거부됩니다.
- fileHandle = await directoryHandle .
getFileHandle
(name, {create
: true }) -
directoryHandle의 로케이터로 위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 파일에 대한 핸들을 반환합니다. 해당 파일이 존재하지 않는 경우, 새 파일을 생성합니다. name이라는 이름을 가진 파일을 생성할 수 없는 경우, 이 메서드는 거부됩니다. 생성이 실패하는 이유는 동일한 이름을 가진 디렉토리가 이미 존재하거나, 이름에 기본 파일 시스템에서 지원되지 않는 문자가 포함되었거나, 보안상의 이유로 사용자 에이전트가 파일 생성을 허용하지 않기로 결정했기 때문일 수 있습니다.
이 작업은 파일이 이미 존재하더라도 쓰기 권한이 필요합니다. 이 핸들이 이미 쓰기 권한을 가지고 있지 않으면, 사용자에게 프롬프트가 표시될 수 있습니다. 쓰기 권한 없이 기존 파일을 가져오려면 이 메서드를
{
로 호출하세요.create
: false }
getFileHandle(name, options)
메서드 단계는 다음과 같습니다:
-
result를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
만약 name이 유효한 파일 이름이 아니라면, global에서 저장 작업을 큐에 추가하여 result를
TypeError
로 거부하고 이 단계를 중단합니다. -
entry를 locator를 입력으로 받아 항목 찾기의 결과로 설정합니다.
-
만약 options["
create
"] 가 true라면:-
accessResult를 "
readwrite
"를 입력으로 하여 entry의 요청 액세스를 실행한 결과로 설정합니다.
-
-
그 외에는:
-
accessResult를 "
read
"를 입력으로 하여 entry의 쿼리 액세스를 실행한 결과로 설정합니다.
-
-
global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:
-
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, accessResult의 오류 이름으로 result를 거부하고 이 단계를 중단합니다. -
만약 entry가
null
이라면, result를 "NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
entry의 자식 항목을 각각 child에 대해 반복합니다:
-
만약 child의 이름이 name과 같다면:
-
만약 child가 디렉토리 항목이라면:
-
result를 "
TypeMismatchError
"DOMException
으로 거부하고 이 단계를 중단합니다.
-
-
result를 locator와 child의 이름, realm을 사용하여 자식
FileSystemFileHandle
생성의 결과로 해결하고 이 단계를 중단합니다.
-
-
-
만약 options["
create
"] 가 false라면:-
result를 "
NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다.
-
-
child를 새 파일 항목으로 설정하며, child의 쿼리 액세스 및 요청 액세스 알고리즘은 entry와 동일하게 합니다.
-
child의 이름을 name으로 설정합니다.
-
child의 수정 타임스탬프를 현재 시간으로 설정합니다.
-
기본 파일 시스템에서 child를 생성하는 동안 예외가 발생하면, 해당 예외로 result를 거부하고 이 단계를 중단합니다.
발생할 수 있는 예외를 더 잘 명시해야 합니다. [Issue #11]
-
result를 locator와 child의 이름, realm을 사용하여 자식
FileSystemFileHandle
생성의 결과로 해결합니다.
-
-
-
result를 반환합니다.
2.4.3. getDirectoryHandle()
메서드
- subdirHandle = await directoryHandle .
getDirectoryHandle
(name)- subdirHandle = await directoryHandle .
getDirectoryHandle
(name, {create
: false }) - subdirHandle = await directoryHandle .
-
directoryHandle의 로케이터로 위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 디렉토리에 대한 핸들을 반환합니다. 해당 디렉토리가 존재하지 않는 경우, 이 메서드는 거부됩니다.
- subdirHandle = await directoryHandle .
getDirectoryHandle
(name, {create
: true }) -
directoryHandle의 로케이터로 위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 디렉토리에 대한 핸들을 반환합니다. 해당 디렉토리가 존재하지 않는 경우 새 디렉토리를 생성합니다. 디렉토리 생성이 실패하면, 이 메서드는 거부됩니다. 생성 실패의 원인은 동일한 이름을 가진 파일이 이미 존재하거나, 이름에 기본 파일 시스템에서 지원되지 않는 문자가 포함되었기 때문일 수 있습니다.
이 작업은 디렉토리가 이미 존재하더라도 쓰기 권한이 필요합니다. 이 핸들이 이미 쓰기 권한을 가지고 있지 않으면, 사용자에게 프롬프트가 표시될 수 있습니다. 쓰기 권한 없이 기존 디렉토리를 가져오려면 이 메서드를
{
로 호출하세요.create
: false }
getDirectoryHandle(name, options)
메서드 단계는 다음과 같습니다:
-
result를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
만약 name이 유효한 파일 이름이 아니라면, global에서 저장 작업을 큐에 추가하여 result를
TypeError
로 거부하고 이 단계를 중단합니다. -
entry를 locator를 입력으로 받아 항목 찾기의 결과로 설정합니다.
-
만약 options["
create
"] 가 true라면:-
accessResult를 "
readwrite
"를 입력으로 하여 entry의 요청 액세스를 실행한 결과로 설정합니다.
-
-
그 외에는:
-
accessResult를 "
read
"를 입력으로 하여 entry의 쿼리 액세스를 실행한 결과로 설정합니다.
-
-
global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:
-
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, accessResult의 오류 이름으로 result를 거부하고 이 단계를 중단합니다. -
만약 entry가
null
이라면, result를 "NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
entry의 자식 항목을 각각 child에 대해 반복합니다:
-
만약 child의 이름이 name과 같다면:
-
만약 child가 파일 항목이라면:
-
result를 "
TypeMismatchError
"DOMException
으로 거부하고 이 단계를 중단합니다.
-
-
result를 locator와 child의 이름, realm을 사용하여 자식
FileSystemDirectoryHandle
생성의 결과로 해결하고 이 단계를 중단합니다.
-
-
-
만약 options["
create
"] 가 false라면:-
result를 "
NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다.
-
-
child를 새 디렉토리 항목으로 설정하며, child의 쿼리 액세스 및 요청 액세스 알고리즘은 entry와 동일하게 합니다.
-
child의 이름을 name으로 설정합니다.
-
기본 파일 시스템에서 child를 생성하는 동안 예외가 발생하면, 해당 예외로 result를 거부하고 이 단계를 중단합니다.
발생할 수 있는 예외를 더 잘 명시해야 합니다. [Issue #11]
-
result를 locator와 child의 이름, realm을 사용하여 자식
FileSystemDirectoryHandle
생성의 결과로 해결합니다.
-
-
-
result를 반환합니다.
2.4.4. removeEntry()
메서드
- await directoryHandle .
removeEntry
(name)- await directoryHandle .
removeEntry
(name, {recursive
: false }) - await directoryHandle .
-
directoryHandle의 로케이터로 위치를 확인할 수 있는 디렉토리 항목에 name이라는 이름의 파일 또는 빈 디렉토리가 포함된 경우, 해당 파일 또는 디렉토리를 삭제하려고 시도합니다.
존재하지 않는 파일이나 디렉토리를 삭제하려고 시도하는 것은 성공으로 간주되지만, 비어 있지 않은 디렉토리를 삭제하려고 하면 Promise가 거부됩니다.
- await directoryHandle .
removeEntry
(name, {recursive
: true }) -
directoryHandle의 로케이터로 위치를 확인할 수 있는 디렉토리 항목에서 name이라는 이름의 파일 시스템 항목을 삭제합니다. 해당 항목이 디렉토리인 경우, 그 내용도 재귀적으로 삭제됩니다.
존재하지 않는 파일이나 디렉토리를 삭제하려고 시도하는 것은 성공으로 간주됩니다.
removeEntry(name, options)
메서드 단계는 다음과 같습니다:
-
result를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
만약 name이 유효한 파일 이름이 아니라면, global에서 저장 작업을 큐에 추가하여 result를
TypeError
로 거부하고 이 단계를 중단합니다. -
entry를 locator를 입력으로 받아 항목 찾기의 결과로 설정합니다.
-
accessResult를 "
readwrite
"를 입력으로 하여 entry의 요청 액세스를 실행한 결과로 설정합니다. -
global에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:
-
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, accessResult의 오류 이름으로 result를 거부하고 이 단계를 중단합니다. -
만약 entry가
null
이라면, result를 "NotFoundError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
entry의 자식 항목을 각각 child에 대해 반복합니다:
-
만약 child의 이름이 name과 같다면:
-
만약 child가 디렉토리 항목이라면:
-
만약 child의 자식 항목이 비어 있지 않으며, options["
recursive
"] 가 false라면:-
result를 "
InvalidModificationError
"DOMException
으로 거부하고 이 단계를 중단합니다.
-
-
-
기본 파일 시스템에서 child를 제거하는 동안 예외가 발생하면, 해당 예외로 result를 거부하고 이 단계를 중단합니다.
참고:
recursive
가 true인 경우, 제거는 비원자적일 수 있습니다. 일부 파일 또는 디렉토리는 제거된 반면, 다른 파일 또는 디렉토리는 여전히 존재할 수 있습니다.발생할 수 있는 예외를 더 잘 명시해야 합니다. [Issue #11]
-
result를
undefined
로 해결합니다.
-
-
-
result를 "
NotFoundError
"DOMException
으로 거부합니다.
-
-
-
result를 반환합니다.
2.4.5. resolve()
메서드
- path = await directory .
resolve
( child ) -
child가 directory와 동일하다면, path는 빈 배열이 됩니다.
child가 directory의 직접적인 자식이라면, path는 child의 이름을 포함하는 배열이 됩니다.
child가 directory의 하위 항목이라면, path는 모든 중간 디렉토리 이름과 마지막 요소로 child의 이름을 포함하는 배열이 됩니다. 예를 들어, directory가
/home/user/project
를 나타내고 child가/home/user/project/foo/bar
를 나타낸다면, 이는['foo', 'bar']
를 반환합니다.그 외 (directory와 child가 관련이 없는 경우), 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 nameof relative_path) { entry= await entry. getDirectory( name); } entry= await entry. getFile( file_ref. name); // 이제 |entry|는 |file_ref|가 나타내는 동일한 디스크 상의 파일을 나타냅니다. assertawait entry. isSameEntry( file_ref) === true ; }
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 기능을 사용할 때, 이 위치는 스트림 객체를 통해 기록된 바이트 수에 따라 진행됩니다.
마찬가지로, ReadableStream
을 FileSystemWritableFileStream
객체로 파이프할 때, 이 위치는 스트림을 통과한 바이트 수에 따라 업데이트됩니다.
getWriter()
는 WritableStreamDefaultWriter
인스턴스를 반환합니다.
FileSystemWritableFileStream
생성은
파일 항목 file과 Realm
realm을 입력으로 받습니다:
-
stream을 새로운
FileSystemWritableFileStream
으로 realm에 설정합니다. -
stream의 [[file]]을 file로 설정합니다.
-
writeAlgorithm을 chunk 인수를 받아들이고 write a chunk 알고리즘을 stream과 chunk로 실행한 결과를 반환하는 알고리즘으로 설정합니다.
-
closeAlgorithm을 다음 단계로 설정합니다:
-
closeResult를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여, 파일 시스템 큐에 실행합니다:
-
accessResult를 "
readwrite
"를 입력으로 하여 file의 쿼리 액세스를 실행한 결과로 설정합니다. -
file의 관련 전역 객체에서 저장 작업을 큐에 추가하여 다음 단계를 실행합니다:
-
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, accessResult의 오류 이름으로 closeResult를 거부하고 이 단계를 중단합니다. -
구현 정의된 악성코드 스캔 및 안전 브라우징 검사를 실행합니다. 이러한 검사가 실패하면, closeResult를 "
AbortError
"DOMException
으로 거부하고 이 단계를 중단합니다. -
stream의 [[file]]의 바이너리 데이터를 stream의 [[buffer]]로 설정합니다. 예외가 발생하면, closeResult를 해당 예외로 거부하고 이 단계를 중단합니다.
참고: 이는 디스크에 기록 중인 파일의 내용을 원자적으로 업데이트할 것으로 예상됩니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
file의 관련 전역 객체에서 저장 작업을 큐에 추가하여, closeResult를
undefined
로 해결합니다.
-
-
-
closeResult를 반환합니다.
-
-
abortAlgorithm을 다음 단계로 설정합니다:
-
이 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
-
highWaterMark를 1로 설정합니다.
-
sizeAlgorithm을
1
을 반환하는 알고리즘으로 설정합니다. -
stream을 다음 값으로 설정합니다: writeAlgorithm은 writeAlgorithm으로, closeAlgorithm은 closeAlgorithm으로, abortAlgorithm은 abortAlgorithm으로, highWaterMark은 highWaterMark으로, 그리고 sizeAlgorithm은 sizeAlgorithm으로 설정합니다.
-
stream을 반환합니다.
FileSystemWritableFileStream
stream과 chunk을 받아 다음 단계를 실행합니다:
-
input을 변환하여 chunk를
FileSystemWriteChunkType
으로 설정합니다. 변환 중 예외가 발생하면, 해당 예외로 거부된 프라미스를 반환합니다. -
p를 새로운 프라미스로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
accessResult를 stream의 [[file]]의 쿼리 액세스를 "
readwrite
"로 실행한 결과로 설정합니다. -
저장 작업을 큐에 추가하여 stream의 관련 전역 객체에서 다음 단계를 실행합니다:
-
만약 accessResult의 권한 상태가 "
granted
"가 아니라면, accessResult의 오류 이름으로 p를 거부하고 이 단계를 중단합니다. -
command를 input["
type
"] 로 설정합니다. 단, input이 딕셔너리가 아닌 경우, "write
"로 설정합니다. -
만약 command가 "
write
"라면:-
만약 input이
undefined
이거나 input이 딕셔너리이고 input["data
"] 가 존재하지 않는다면, p를TypeError
로 거부하고 이 단계를 중단합니다. -
data를 input["
data
"] 로 설정합니다. 단, input이 딕셔너리가 아닌 경우, input으로 설정합니다. -
writePosition을 stream의 [[seekOffset]]로 설정합니다.
-
만약 input이 딕셔너리이고 input["
position
"] 존재한다면, writePosition을 input["position
"]로 설정합니다. -
oldSize를 stream의 [[buffer]]의 길이로 설정합니다.
-
만약 data가
BufferSource
라면, dataBytes를 복사본으로 설정합니다. -
그 외, 만약 data가
Blob
이라면: -
그 외:
-
dataBytes를 UTF-8로 인코딩한 결과로 설정합니다.
-
만약 writePosition이 oldSize보다 크다면, writePosition - oldSize 만큼의 0x00 (NUL) 바이트를 stream의 [[buffer]] 끝에 추가합니다.
참고: 구현체는 건너뛴 파일 내용이 실제로 NUL 바이트로 채워진 것처럼 동작해야 합니다. 이것이 실제로 디스크에 작성되어 공간을 차지해야 한다는 의미는 아닙니다. 대부분의 파일 시스템은 이러한 NUL 바이트가 실제 디스크 공간을 차지하지 않는 희소 파일을 지원합니다.
-
head를 바이트 시퀀스로 설정하며, stream의 [[buffer]]의 처음 writePosition 바이트를 포함합니다.
-
tail를 빈 바이트 시퀀스로 설정합니다.
-
만약 writePosition + data의 길이가 oldSize보다 작다면:
-
tail를 바이트 시퀀스로 설정하며, stream의 [[buffer]]의 마지막 oldSize - (writePosition + data의 길이) 바이트를 포함합니다.
-
-
stream의 [[buffer]]를 head, data, tail의 연결로 설정합니다.
-
만약 이전 단계에서 stream의 [[buffer]]를 수정하는 작업이 저장소 할당량을 초과하여 실패한 경우, p를 "
QuotaExceededError
"DOMException
로 거부하고 이 단계를 중단하며, stream의 [[buffer]]는 수정하지 않습니다.참고: 저장소 할당량은 버킷 파일 시스템에 저장된 파일에만 적용됩니다. 그러나 이 작업은 여전히 다른 파일에서도 실패할 수 있습니다. 예를 들어, 쓰기를 시도하는 디스크의 공간이 부족한 경우입니다.
-
stream의 [[seekOffset]]를 writePosition + data의 길이로 설정합니다.
-
Resolve p.
-
-
그 외, 만약 command가 "
seek
"라면: -
그 외, 만약 command가 "
truncate
"라면:-
만약 chunk["
size
"] 가 존재하지 않는다면, p를TypeError
로 거부하고 이 단계를 중단합니다. -
newSize를 chunk["
size
"]로 설정합니다. -
oldSize를 stream의 [[buffer]]의 길이로 설정합니다.
-
만약 newSize가 oldSize보다 크다면:
-
stream의 [[buffer]]를 stream의 [[buffer]]와 newSize - oldSize 만큼의
0x00
바이트를 포함하는 바이트 시퀀스를 연결하여 설정합니다. -
만약 이전 단계의 작업이 저장소 할당량 초과로 인해 실패한 경우, p를 "
QuotaExceededError
"DOMException
로 거부하고 이 단계를 중단하며, stream의 [[buffer]]는 수정하지 않습니다.참고: 저장소 할당량은 버킷 파일 시스템에 저장된 파일에만 적용됩니다. 그러나 이 작업은 여전히 다른 파일에서도 실패할 수 있습니다. 예를 들어, 쓰기를 시도하는 디스크의 공간이 부족한 경우입니다.
-
-
그 외, 만약 newSize가 oldSize보다 작다면:
-
stream의 [[buffer]]를 stream의 [[buffer]]의 처음 newSize 바이트를 포함하는 바이트 시퀀스로 설정합니다.
-
-
만약 stream의 [[seekOffset]]이 newSize보다 크다면, stream의 [[seekOffset]]를 newSize로 설정합니다.
-
Resolve p.
-
-
-
p를 반환합니다.
2.5.1. write()
메서드
- await stream .
write
(data)- await stream .
write
({type
: "write
",data
: data }) - await stream .
-
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)
메서드
단계는 다음과 같습니다:
-
writer를 writer 가져오기를 통해 this에서 가져온 결과로 설정합니다.
-
result를 청크 쓰기를 writer와 data를 사용하여 실행한 결과로 설정합니다.
-
writer 해제를 실행합니다.
-
result를 반환합니다.
2.5.2. seek()
메서드
- await stream .
seek
(position) -
파일 상단에서 position 바이트 떨어진 위치로 현재 파일 커서 오프셋을 업데이트합니다.
seek(position)
메서드 단계는 다음과 같습니다:
2.5.3. truncate()
메서드
truncate(size)
메서드 단계는 다음과 같습니다:
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
생성은
파일 항목 file과 Realm
realm을 입력으로 받습니다:
-
handle을 새로운
FileSystemSyncAccessHandle
으로 realm에 설정합니다. -
handle의 [[file]]을 file로 설정합니다.
-
handle의 [[state]]를 "
open
"으로 설정합니다. -
handle을 반환합니다.
2.6.1. read()
메서드
외부에서 수정된 파일을 읽을 때 Access Handle이 어떻게 반응해야 하는지 명시하세요. [Issue #35]
read(buffer, FileSystemReadWriteOptions
:
options)
메서드 단계는 다음과 같습니다:
-
만약 this의 [[state]]가 "
closed
"라면, "InvalidStateError
"DOMException
을 throw합니다. -
bufferSize를 buffer의 바이트 길이로 설정합니다.
-
fileSize를 fileContents의 길이로 설정합니다.
-
readStart를 options["
at
"] 로 설정합니다. 단, options["at
"] 가 존재하지 않는다면, this의 파일 위치 커서로 설정합니다. -
만약 기본 파일 시스템이 readStart 파일 오프셋에서 읽기를 지원하지 않는다면, throw
TypeError
. -
만약 readStart가 fileSize보다 크다면:
-
readEnd를 readStart + (bufferSize − 1)로 설정합니다.
-
만약 readEnd가 fileSize보다 크다면, readEnd를 fileSize로 설정합니다.
-
bytes를 fileContents의 readStart에서 readEnd까지의 바이트를 포함하는 바이트 시퀀스로 설정합니다.
-
result를 bytes의 길이로 설정합니다.
-
만약 이전 단계에서 fileContents에서 읽기 작업이 실패했다면:
-
부분적으로 읽은 바이트가 있고 bytes에 읽힌 바이트 수를 아는 경우, result를 읽은 바이트 수로 설정합니다.
-
그 외에는 result를 0으로 설정합니다.
-
-
arrayBuffer를 buffer의 기본 버퍼로 설정합니다.
-
Write bytes를 arrayBuffer에 씁니다.
-
result를 반환합니다.
2.6.2. write()
메서드
write(buffer, FileSystemReadWriteOptions
:
options)
메서드 단계는 다음과 같습니다:
-
만약 this의 [[state]]가 "
closed
"라면, "InvalidStateError
"DOMException
을 throw합니다. -
writePosition를 options["
at
"] 로 설정합니다. 단, options["at
"] 가 존재하지 않는다면, this의 파일 위치 커서로 설정합니다. -
만약 기본 파일 시스템이 writePosition 파일 오프셋에서 쓰기를 지원하지 않는다면, throw
TypeError
. -
oldSize를 fileContents의 길이로 설정합니다.
-
bufferSize를 buffer의 바이트 길이로 설정합니다.
-
만약 writePosition가 oldSize보다 크다면, writePosition − oldSize 0x00 (NUL) 바이트를 fileContents 끝에 추가합니다.
참고: 구현체는 건너뛴 파일 내용이 실제로 NUL 바이트로 채워진 것처럼 동작해야 합니다. 이것이 실제로 디스크에 작성되어 공간을 차지해야 한다는 의미는 아닙니다. 대부분의 파일 시스템은 이러한 NUL 바이트가 실제 디스크 공간을 차지하지 않는 희소 파일을 지원합니다.
-
head를 fileContents의 처음 writePosition 바이트를 포함하는 바이트 시퀀스로 설정합니다.
-
tail를 빈 바이트 시퀀스로 설정합니다.
-
만약 writePosition + bufferSize가 oldSize보다 작다면:
-
tail를 fileContents의 마지막 oldSize − (writePosition + bufferSize) 바이트를 포함하는 바이트 시퀀스로 설정합니다.
-
-
만약 newSize − oldSize가 사용 가능한 저장소 할당량을 초과한다면, throw "
QuotaExceededError
"DOMException
. -
this의 [[file]]의 바이너리 데이터를 head, buffer의 내용, tail의 연결로 설정합니다.
참고: 버퍼의 내용을 접근하는 메커니즘은 의도적으로 모호하게 설정되었습니다. 구현체는 성능을 중점으로 하여 호스트 운영 체제에 직접 쓰기 호출을 실행하는 방식을 선택할 가능성이 높습니다 (버퍼의 복사본을 생성하는 대신), 이는 쓰기 순서와 부분 쓰기의 결과에 대한 자세한 명세를 방해합니다.
-
만약 이전 단계를 통해 this의[[file]]의 바이너리 데이터를 수정하는 작업이 실패했다면:
-
부분적으로 기록된 바이트가 있고 buffer에서 기록된 바이트 수를 아는 경우:
-
그 외에는 throw "
InvalidStateError
"DOMException
.
-
-
bufferSize를 반환합니다.
2.6.3. truncate()
메서드
truncate(newSize)
메서드 단계는 다음과 같습니다:
-
만약 this의 [[state]]가 "
closed
"라면, "InvalidStateError
"DOMException
을 throw합니다. -
만약 기본 파일 시스템이 파일 크기를 newSize로 설정하는 것을 지원하지 않는다면, throw
TypeError
. -
만약 newSize가 oldSize보다 크다면:
-
만약 newSize − oldSize가 사용 가능한 저장소 할당량을 초과한다면, throw "
QuotaExceededError
"DOMException
. -
this의 [[file]]를 fileContents와 newSize − oldSize 0x00 바이트를 포함하는 바이트 시퀀스로 연결하여 설정합니다.
-
만약 이전 단계에서 this의 [[file]]의 바이너리 데이터를 수정하는 작업이 실패했다면, "
InvalidStateError
"DOMException
을 throw합니다.
-
-
그 외, 만약 newSize가 oldSize보다 작다면:
-
this의 [[file]]를 fileContents의 처음 newSize 바이트를 포함하는 바이트 시퀀스로 설정합니다.
-
만약 이전 단계에서 this의 [[file]]의 바이너리 데이터를 수정하는 작업이 실패했다면, "
InvalidStateError
"DOMException
을 throw합니다.
-
2.6.4. getSize()
메서드
- handle .
getSize()
-
handle과 연결된 파일의 크기를 바이트 단위로 반환합니다.
getSize()
메서드 단계는 다음과 같습니다:
-
만약 this의 [[state]]가 "
closed
"라면, "InvalidStateError
"DOMException
을 throw합니다.
2.6.5. flush()
메서드
flush()
메서드 단계는 다음과 같습니다:
-
만약 this의 [[state]]가 "
closed
"라면, "InvalidStateError
"DOMException
을 throw합니다. -
파일 내용의 모든 캐시된 수정 사항을 파일 시스템의 기본 저장 장치로 전송하려고 시도합니다.
참고: 이는 플러싱(flushing)이라고도 알려져 있습니다. 일부 메모리 파일 시스템과 같이 "디스크"로 플러시할 필요가 없는 파일 시스템에서는 이 작업이 아무 작업도 수행하지 않을 수 있습니다.
2.6.6. close()
메서드
close()
메서드 단계는 다음과 같습니다:
-
lockReleased를 false로 설정합니다.
-
다음 단계를 큐에 추가하여 파일 시스템 큐에 실행합니다:
-
잠금을 해제합니다. file에 대해.
-
lockReleased를 true로 설정합니다.
-
-
Pause하여 lockReleased가 true가 될 때까지 대기합니다.
참고: 이 메서드는 모든 파일 수정 사항이 기본 저장 장치에 즉시 반영될 것을 보장하지
않습니다.
이러한 보장이 필요한 경우 flush()
메서드를 먼저 호출하세요.
3. 버킷 파일 시스템 접근
버킷 파일 시스템은
저장소 엔드포인트이며,
식별자는 "fileSystem"
,
유형은 « "local" »
,
할당량은 null입니다.
저장소 엔드포인트는 [storage] 자체에서 정의되어야 하며, 여기에서 정의되지 않아야 합니다. 따라서 이를 해당 표에 병합하세요.
참고: 사용자 에이전트는 일반적으로 버킷 파일 시스템의 내용을 디스크에 저장하여 구현하지만, 이는 사용자가 쉽게 접근할 수 있도록 의도된 것은 아닙니다. 마찬가지로, 버킷 파일 시스템의 하위 항목 이름과 일치하는 파일이나 디렉토리가 존재할 것이라는 기대도 없습니다.
[SecureContext ]partial interface StorageManager {Promise <FileSystemDirectoryHandle >getDirectory (); };
- directoryHandle = await navigator . storage .
getDirectory()
-
버킷 파일 시스템의 루트 디렉토리를 반환합니다.
getDirectory()
메서드 단계는 다음과 같습니다:
-
environment를 현재 설정 객체로 설정합니다.
-
map를 environment와
"fileSystem"
을 사용하여 로컬 저장소 병 맵 획득을 실행한 결과로 설정합니다. 실패를 반환하면, "SecurityError
"DOMException
으로 거부된 프라미스를 반환합니다. -
만약 map["root"]이 존재하지 않는다면:
-
path를 « 빈 문자열 »로 설정합니다.
-
handle을 새로운
FileSystemDirectoryHandle
생성을 실행한 결과로 설정합니다. root와 path를 현재 Realm에서 사용하여.참고: root는 관련 식별 정보(예: 저장소 버킷)를 포함할 수 있습니다.
-
단언: 항목 위치 찾기를 handle의 로케이터 를 사용하여 실행하면 map["root"]와 동일한 디렉토리 항목을 반환합니다.
-
프라미스가 해결된 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)가 작성했습니다.
지적 재산권
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). 이 작업은 Creative Commons Attribution 4.0 International License 하에 라이선스가 부여됩니다. 소스 코드에 통합된 일부는 BSD 3-Clause License 하에 라이선스가 부여됩니다.
이것이 현행 표준입니다. 특허 검토 버전에 관심이 있는 분들은 현행 표준 검토 초안을 참고하세요.