파일 시스템 액세스

커뮤니티 그룹 초안 보고서,

현재 버전:
https://wicg.github.io/file-system-access/
이슈 추적:
GitHub
명세 내 인라인
에디터:
(Google)
이전 에디터:
(Google)
(Google)

요약

이 문서는 [FS]의 API를 확장하여 개발자가 사용자의 로컬 디바이스에 있는 파일과 상호작용하는 강력한 웹 앱을 만들 수 있도록 지원합니다. 파일 읽기 기능을 위해 File API를 기반으로 하며, 파일을 수정하고 디렉터리 작업을 할 수 있는 새로운 API 표면을 추가합니다.

이 문서의 현황

본 명세서는 Web Platform Incubator Community Group에서 발행하였습니다. W3C 표준이 아니며 W3C 표준 트랙에도 포함되어 있지 않습니다. W3C 커뮤니티 기여자 라이선스 계약(CLA)에 따라 제한적인 옵트아웃과 기타 조건이 적용됩니다. W3C 커뮤니티 및 비즈니스 그룹에 대해 더 알아보세요.

1. 소개

이 섹션은 규범적이지 않습니다.

이 API는 개발자가 사용자의 디바이스에 있는 (웹이 아닌) 다른 앱과 디바이스의 파일 시스템을 통해 상호작용하는 강력한 앱을 구축할 수 있도록 합니다. 이 기능이 기대되는 대표적인 응용 프로그램으로는 IDE, 사진 및 비디오 편집기, 텍스트 편집기 등이 있습니다. 사용자가 웹 앱에 접근 권한을 부여한 후, 이 API를 통해 앱은 사용자의 디바이스에 있는 파일 및 폴더를 직접 읽거나 변경사항을 저장할 수 있습니다. 파일 읽기 및 쓰기 기능을 넘어서, 이 API는 디렉터리를 열어 그 내용을 나열하는 기능도 제공합니다. 또한, 웹 앱은 이 API를 이용해 접근 권한이 부여된 파일 및 디렉터리의 참조를 저장할 수 있으므로, 사용자가 동일한 파일을 다시 선택하지 않아도 웹 앱이 나중에 동일한 콘텐츠에 다시 접근할 수 있습니다.

이 API는 사용자의 상호작용이 파일 및 디렉터리 선택기 대화상자를 통해 이루어진다는 점에서 <input type=file><input type=file webkitdirectory> [entries-api] 와 유사합니다. 하지만 이 API는 순수하게 자바스크립트 API이며, 폼 또는 input 요소와 통합되지 않습니다.

이 API는 [FS]의 API를 확장하며, 버킷 파일 시스템을 정의합니다. 이를 통해 웹사이트는 사용자에게 먼저 접근 권한을 요청하지 않고도 접근할 수 있습니다.

2. 파일 및 디렉터리

2.1. 개념

유효한 접미사 코드 포인트코드 포인트ASCII 영숫자, U+002B (+), 또는 U+002E (.)인 값입니다.

참고: 이러한 코드 포인트는 대부분의 기존 파일 형식을 지원하기 위해 선택되었습니다. 대부분의 파일 확장자는 순수하게 영숫자이지만, .tar.gz 와 같은 복합 확장자나 C++ 소스 파일의 .c++ 와 같은 확장자도 자주 사용되므로 +와 .을 허용된 코드 포인트에 포함했습니다.

2.2. 권한

"file-system" 강력한 기능의 권한 관련 알고리즘과 타입은 다음과 같이 정의됩니다:

permission descriptor type

FileSystemPermissionDescriptor 는 다음과 같이 정의됩니다:

enum FileSystemPermissionMode {
  "read",
  "readwrite"
};

dictionary FileSystemPermissionDescriptor : PermissionDescriptor {
  required FileSystemHandle handle;
  FileSystemPermissionMode mode = "read";
};
permission state constraints
FileSystemPermissionDescriptor desc에 대한 permission state constraints를 결정하려면, 다음 절차를 따르세요:
  1. entrydesc["handle"]의 entry로 둔다.

  2. 만약 entry파일 시스템 엔트리버킷 파일 시스템에서 나타낸다면, 이 디스크립터의 권한 상태는 항상 "granted"여야만 합니다.

  3. 그렇지 않고 entry부모 가 null이 아니라면, 이 디스크립터의 권한 상태mode가 같고, entry부모를 나타내는 handle이 있는 디스크립터의 권한 상태와 같아야 합니다.

  4. 그 외에 desc["mode"] 값이 "readwrite"라면:

    1. read statehandle만 같고 mode가 "read"인 디스크립터의 권한 상태로 둡니다.

    2. 만약 read state가 "granted"가 아니라면, 이 디스크립터의 권한 상태read state와 같아야 합니다.

이러한 검사가 엔트리에 더 이상 연결되지 않도록 해야 합니다. [whatwg/fs Issue #101]

permission request algorithm
FileSystemPermissionDescriptor descPermissionStatus status가 주어졌을 때, 다음 단계를 실행하세요:
  1. descstatus에 대해 기본 권한 쿼리 알고리즘을 실행합니다.

  2. statusstate 가 "prompt" 가 아니면, 이 단계를 중단합니다.

  3. settingsdesc["handle"]의 관련 설정 객체로 둡니다.

  4. globalsettingsglobal object로 둡니다.

  5. globalWindow 가 아니면, "SecurityError" DOMExceptionthrow 합니다.

  6. globaltransient activation이 없으면, "SecurityError" DOMExceptionthrow 합니다.

  7. settingsoriginsettingstop-level origin동일 출처가 아니면, "SecurityError" DOMExceptionthrow 합니다.

  8. desc를 사용하기 위해 권한을 요청합니다.

  9. descstatus에 대해 기본 권한 쿼리 알고리즘을 실행합니다.

이상적으로는 이 사용자 활성화 요구사항이 상위 수준에서 정의되는 것이 더 좋겠습니다. [WICG/permissions-request Issue #2]

FileSystemHandle handleFileSystemPermissionMode mode를 받아 파일 시스템 권한을 쿼리하는 방법은 다음과 같습니다:
  1. descFileSystemPermissionDescriptor로 둡니다.

  2. desc["name"]를 "file-system"으로 설정합니다.

  3. desc["handle"]에 handle을 설정합니다.

  4. desc["mode"]에 mode를 설정합니다.

  5. desc권한 상태를 반환합니다.

FileSystemHandle handleFileSystemPermissionMode mode를 받아 파일 시스템 권한을 요청하는 방법은 다음과 같습니다:
  1. descFileSystemPermissionDescriptor로 둡니다.

  2. desc["name"]를 "file-system"으로 설정합니다.

  3. desc["handle"]에 handle을 설정합니다.

  4. desc["mode"]에 mode를 설정합니다.

  5. desc에 대해 PermissionStatus 생성의 결과를 status에 할당합니다.

  6. "file-system" 기능, descstatus에 대해 permission request algorithm을 실행합니다.

  7. desc권한 상태를 반환합니다.

현재 FileSystemPermissionMode 값은 "read" 또는 "readwrite" 만 가능합니다. 앞으로는 쓰기 전용 핸들 지원을 위해 "write" 모드를 추가할 수도 있습니다. [Issue #119]

2.3. FileSystemHandle 인터페이스

dictionary FileSystemHandlePermissionDescriptor {
  FileSystemPermissionMode mode = "read";
};

[Exposed=(Window,Worker), SecureContext, Serializable]
partial interface FileSystemHandle {
  Promise<PermissionState> queryPermission(optional FileSystemHandlePermissionDescriptor descriptor = {});
  Promise<PermissionState> requestPermission(optional FileSystemHandlePermissionDescriptor descriptor = {});
};

2.3.1. queryPermission() 메서드

status = await handle . queryPermission({ mode : "read" })
status = await handle . queryPermission()
status = (await navigator.permissions.query({ name : "file-system", handle : handle })).state

이 핸들(handle)의 읽기 권한 현재 상태를 조회합니다. 만약 이 호출이 "prompt" 를 반환하면, 웹사이트는 해당 핸들에 대한 어떤 작업을 수행하기 전에 requestPermission() 을 호출해야 합니다. 만약 "denied" 를 반환하면 모든 연산은 거부됩니다.

보통 로컬 파일 시스템 핸들 생성기들이 반환하는 핸들은 처음에는 읽기 권한 상태에 대해 "granted" 를 반환하지만, 사용자가 권한을 취소한 경우를 제외하고는 IndexedDB에서 가져온 핸들은 "prompt" 를 반환할 가능성도 있습니다.

status = await handle . queryPermission({ mode : "readwrite" })
status = (await navigator.permissions.query({ name : "file-system", handle : handle, mode : "readwrite" }).state

이 핸들(handle)의 쓰기 권한 현재 상태를 조회합니다. 만약 이것이 "prompt" 를 반환하면, 파일이나 디렉터리를 수정하려고 시도할 때 사용자 활성화가 필요하며 사용자에게 확인 프롬프트가 표시됩니다. 그러나 이 핸들의 읽기 권한 상태도 "prompt" 인 경우에는 웹사이트가 requestPermission() 을 호출해야 합니다. 읽기 접근에 대해서는 파일이나 디렉터리에서 읽기를 시도할 때 자동으로 프롬프트가 발생하지 않습니다.

권한 API의 query() 메서드와의 통합은 아직 Chrome에 구현되어 있지 않습니다.

queryPermission(descriptor) 메서드는 호출되었을 때 다음 단계를 실행해야 합니다:
  1. result새로운 프라미스로 둡니다.

  2. 다음 단계를 병렬로 실행합니다:

    1. state지정된 파일 시스템 권한을 조회하기의 결과로 둡니다. 이때 대상은 this 이고 descriptor["mode"]입니다.

    2. Resolve resultstate 로 합니다.

  3. result를 반환합니다.

2.3.2. requestPermission() 메서드

status = await handle . requestPermission({ mode : "read" })
status = await handle . requestPermission()

이 핸들(handle)의 읽기 권한 상태가 "prompt" 이외의 값이면, 이 호출은 그 상태를 그대로 반환합니다. 만약 상태가 "prompt" 인 경우에는 사용자 활성화가 필요하며 사용자에게 확인 프롬프트가 표시됩니다. 이후 사용자의 응답에 따라 새로운 읽기 권한 상태가 반환됩니다.

status = await handle . requestPermission({ mode : "readwrite" })

이 핸들(handle)의 쓰기 권한 상태가 "prompt" 이외의 값이면, 이 호출은 그 상태를 그대로 반환합니다. 만약 이 핸들의 읽기 권한 상태가 "denied" 라면, 이 상태를 반환합니다.

그렇지 않다면 쓰기 권한의 상태가 "prompt" 이며 이 경우 사용자에게 확인 프롬프트가 표시됩니다. 이후 사용자가 선택한 내용에 따라 새로운 쓰기 권한 상태가 반환됩니다.

requestPermission(descriptor) 메서드는 호출되었을 때 다음 단계를 실행해야 합니다:
  1. result새로운 프라미스로 둡니다.

  2. 다음 단계를 병렬로 실행합니다:

    1. state지정된 파일 시스템 권한을 요청하기의 결과로 둡니다. 이때 대상은 this 이고 descriptor["mode"] 입니다. 만약 그 과정에서 예외가 발생하면, 해당 예외로 resultreject 하고 중단합니다.

    2. Resolve resultstate 로 합니다.

  3. result를 반환합니다.

3. 로컬 파일 시스템 접근

enum WellKnownDirectory {
  "desktop",
  "documents",
  "downloads",
  "music",
  "pictures",
  "videos",
};

typedef (WellKnownDirectory or FileSystemHandle) StartInDirectory;

dictionary FilePickerAcceptType {
    USVString description = "";
    record<USVString, (USVString or sequence<USVString>)> accept;
};

dictionary FilePickerOptions {
    sequence<FilePickerAcceptType> types;
    boolean excludeAcceptAllOption = false;
    DOMString id;
    StartInDirectory startIn;
};

dictionary OpenFilePickerOptions : FilePickerOptions {
    boolean multiple = false;
};

dictionary SaveFilePickerOptions : FilePickerOptions {
    USVString? suggestedName;
};

dictionary DirectoryPickerOptions {
    DOMString id;
    StartInDirectory startIn;
    FileSystemPermissionMode mode = "read";
};

[SecureContext]
partial interface Window {
    Promise<sequence<FileSystemFileHandle>> showOpenFilePicker(optional OpenFilePickerOptions options = {});
    Promise<FileSystemFileHandle> showSaveFilePicker(optional SaveFilePickerOptions options = {});
    Promise<FileSystemDirectoryHandle> showDirectoryPicker(optional DirectoryPickerOptions options = {});
};

showOpenFilePicker(), showSaveFilePicker()showDirectoryPicker() 메서드들은 합쳐서 로컬 파일 시스템 핸들 생성기들로 불립니다.

참고: 이 규격에서 "로컬 파일 시스템"이라 칭하는 것은 반드시 로컬 기기의 파일 시스템만을 의미하지 않습니다. 우리가 말하는 로컬 파일 시스템은 클라우드 제공자에 의해 백업될 수도 있습니다. 예를 들어 Chrome OS에서는 이 파일 선택기가 Google Drive의 파일 및 디렉터리도 선택할 수 있도록 합니다.

Chrome 버전 85 이전에서는, 이것이 일반적인 chooseFileSystemEntries 메서드로 구현되었습니다.

3.1. 로컬 파일 시스템 권한

프롬프트에서 로컬 파일 시스템 핸들 생성기들가 반환한 특정 파일들을 사용자가 선택했다는 사실은, 사용자 에이전트가 해당 파일들에 대해 웹사이트에 읽기 접근을 허용하려는 사용자의 의도로 간주해야 합니다. 따라서 로컬 파일 시스템 핸들 생성기들 중 하나가 반환하는 프라미스가 해결될 때, permission statehandle 이 반환된 핸들로 설정되고, mode 가 "read" 로 설정되어 있으면 "granted" 여야 합니다.

또한 showSaveFilePicker 호출의 경우에는, permission statehandle 을 반환된 핸들로 설정하고, mode 가 "readwrite" 로 설정되어 있으면 "granted" 여야 합니다.

환경(environment)이 파일 선택기를 표시할 수 있는지 검증하려면 다음 단계를 실행합니다:

  1. 만약 environmentoriginopaque origin이면, "SecurityError" DOMException로 거부된 프라미스를 반환합니다.

  2. 만약 environmentorigintop-level origin과 동일 출처가 아니면, "SecurityError" DOMException로 거부된 프라미스를 반환합니다.

  3. globalenvironmentglobal object로 둡니다.

  4. 만약 globaltransient activation을 가지고 있지 않다면, "SecurityError" DOMExceptionthrow 합니다.

3.2. 파일 선택기 옵션

3.2.1. 허용된 파일 유형

showOpenFilePicker(options)showSaveFilePicker(options) 메서드는 웹사이트가 파일 선택기가 사용자가 선택할 수 있도록 할 파일 유형을 지정할 수 있게 하는 FilePickerOptions 인수를 받아들입니다.

types 의 각 항목은 파일 선택기에 표시되는 파일을 필터링하기 위한 단일 사용자 선택 가능한 옵션을 지정합니다.

각 옵션은 선택적 description 과 여러 MIME 유형 및 확장자로 구성됩니다 (MIME 유형에서 확장자 목록으로의 매핑으로 지정). 설명이 제공되지 않으면 하나가 생성됩니다. 확장자는 "."으로 시작하고 유효한 접미사 코드 포인트만 포함하는 문자열이어야 합니다. 또한 확장자는 16 코드 포인트의 길이로 제한됩니다.

완전한 MIME 유형 외에도 "*"는 MIME 유형의 하위 유형으로 사용할 수 있으며, 예를 들어 "image/*"로 모든 이미지 형식을 일치시킬 수 있습니다.

웹사이트는 항상 각 옵션에 대해 MIME 유형과 파일 확장자를 모두 제공해야 합니다. 파일 확장자만을 사용하여 파일 유형을 설명하는 플랫폼에서는 사용자 에이전트가 확장자에 일치할 수 있으며, 확장자를 사용하지 않는 플랫폼에서는 사용자 에이전트가 MIME 유형에 일치할 수 있습니다.

기본적으로 파일 선택기는 사용자가 어떤 파일이든 선택할 수 있도록 필터를 적용하지 않는 옵션도 포함합니다. excludeAcceptAllOptiontrue로 설정하여 파일 선택기에 이 옵션을 포함하지 마십시오.

예를 들어, 다음 옵션은 사용자가 세 가지 다른 필터 중 하나를 선택할 수 있도록 합니다. 하나는 텍스트 파일(일반 텍스트 또는 HTML), 하나는 이미지, 그리고 세 번째는 필터를 적용하지 않고 사용자가 어떤 파일이든 선택할 수 있도록 합니다.

const options = {
  types: [
    {
      description: 'Text Files',
      accept: {
        'text/plain': ['.txt', '.text'],
        'text/html': ['.html', '.htm']
      }
    },
    {
      description: 'Images',
      accept: {
        'image/*': ['.png', '.gif', '.jpeg', '.jpg']
      }
    },
  ],
};

반면에, 다음 예제는 사용자가 SVG 파일만 선택할 수 있도록 합니다. 대화 상자는 필터를 적용하지 않는 옵션을 표시하지 않습니다.

const options = {
  types: [
    {
      accept: {
        'image/svg+xml': '.svg'
      }
    },
  ],
  excludeAcceptAllOption: true
};
FilePickerOptions options가 주어지면 수락 유형을 처리하려면 다음 단계를 실행합니다:
  1. accepts options를 설명과 필터로 구성된 빈 목록으로 둡니다.

  2. options["types"]의 각 type에 대해:

    1. type["accept"]의 각 typeStringsuffixes에 대해:

      1. parsedTypetypeString으로 MIME 유형을 파싱한 결과로 둡니다.

      2. parsedType가 실패하면, TypeErrorthrow 합니다.

      3. parsedTypeparameters가 비어 있지 않으면, TypeErrorthrow 합니다.

      4. suffixes가 문자열이면:

        1. suffixes가 주어진 접미사를 검증합니다.

      5. 그렇지 않으면, suffixes의 각 suffix에 대해:

        1. suffix가 주어진 접미사를 검증합니다.

    2. filter를 이 단계로 둡니다. filename (문자열)과 type (MIME 유형)가 주어지면:

      1. type["accept"]의 각 typeStringsuffixes에 대해:

      2. parsedTypetypeString으로 MIME 유형을 파싱한 결과로 둡니다.

        1. parsedTypesubtype가 "*"이면:

          1. parsedTypetype이 "*"이면 true를 반환합니다.

          2. parsedTypetypetypetype과 같으면 true를 반환합니다.

        2. parsedTypeessencetypeessence와 같으면 true를 반환합니다.

        3. suffixes가 문자열이면, suffixes를 « suffixes »로 설정합니다.

        4. suffixes의 각 suffix에 대해:

          1. filenamesuffix로 끝나면 true를 반환합니다.

      3. false를 반환합니다.

    3. descriptiontype["description"]으로 둡니다.

    4. description가 빈 문자열이면, filter를 설명하는 사용자 이해 가능한 문자열로 description을 설정합니다.

    5. (description, filter)를 accepts options추가합니다.

  3. accepts options비어 있거나, options["excludeAcceptAllOption"] 이 false이면:

    1. description를 "all files"를 설명하는 사용자 이해 가능한 문자열로 둡니다.

      1. filtertrue를 반환하는 알고리즘으로 둡니다.

      2. (description, filter)를 accepts options추가합니다.

  4. accepts options가 비어 있으면, TypeErrorthrow 합니다.

  5. accepts options를 반환합니다.

suffix접미사를 검증하려면 다음 단계를 실행합니다:
  1. suffix가 "."으로 시작하지 않으면, TypeErrorthrow 합니다.

  2. 만약 suffix코드 포인트유효한 접미사 코드 포인트가 아닌 것이 포함되어 있다면, throw TypeError를 발생시킵니다.

  3. suffix가 "."으로 끝나면, TypeErrorthrow 합니다.

  4. suffix길이가 16보다 크면, TypeErrorthrow 합니다.

3.2.2. 시작 디렉터리

idstartIn 필드를 지정하여 파일 선택기가 열릴 디렉터리를 제안할 수 있습니다.

이러한 옵션이 지정되지 않으면, 사용자 에이전트는 마지막으로 파일이나 디렉터리를 선택한 디렉터리를 기억하며, 새로운 선택기는 해당 디렉터리에서 시작합니다. id 를 지정하면 사용자 에이전트는 다른 ID에 대해 다른 디렉터리를 기억할 수 있습니다 (사용자 에이전트는 제한된 수의 ID에 대해서만 디렉터리를 기억합니다).

// 이 ID에 대한 매핑이 존재하면, 이 디렉터리에서 시작합니다.
// 그렇지 않으면, 이 ID에 대한 매핑이 생성되며,
// 파일 선택기 호출의 결과 디렉터리에 매핑됩니다.
const options = {
  id: 'foo',
};

startInFileSystemFileHandle 로 지정하면 대화 상자가 해당 파일의 부모 디렉터리에서 시작됩니다. 반면 FileSystemDirectoryHandle 을 전달하면 대화 상자가 전달된 디렉터리에서 시작됩니다. 명시적 id 가 또한 전달되더라도 이들은 우선합니다.

예를 들어, FileSystemDirectoryHandle project_dir가 주어지면 다음은 해당 디렉터리에서 시작하는 파일 선택기를 표시합니다:

// 선택기는 |project_dir|의 디렉터리에서 열립니다. 'foo'가 유효한 매핑을 가지고 있는지 여부와 무관합니다.
const options = {
  id: 'foo',
  startIn: |project_dir|,
};

idstartIn 필드는 선택기가 열릴 디렉터리만 제어합니다. 위의 예제에서는 선택기가 파일 선택기 작업을 완료한 후 id 'foo'가 project_dir과 동일한 디렉터리에 매핑된다고 가정할 수 없습니다.

startInWellKnownDirectory 로 지정하면 대화 상자가 해당 디렉터리에서 시작되며, 명시적 id 가 또한 전달되어 유효한 디렉터리에 대한 매핑이 있는 경우가 아니면 그렇습니다.

아래는 idstartInWellKnownDirectory 로 지정하는 예제입니다. 주어진 ID에 대한 기존 매핑이 존재하면 해당 매핑이 사용됩니다. 그렇지 않으면 WellKnownDirectory 에서 제안한 경로가 사용됩니다.

// ID 'foo'에 대해 처음 지정합니다. 이는 디렉터리에 매핑되지 않습니다.
// 파일 선택기는 다운로드 디렉터리에서 열리도록 폴백됩니다. TODO: link this.
const options = {
  id: 'foo',  // 매핑되지 않음.
  startIn: "downloads",  // 여기서 시작.
};

// 나중에...

// ID 'foo'는 매핑될 수도 있고 아닐 수도 있습니다. 예를 들어, 이 ID에 대한 매핑이
// 제거되었을 수 있습니다.
const options = {
  id: 'foo',  // 매핑될 수도 있음. 그렇다면 여기서 시작.
  startIn: "downloads",  // 그렇지 않으면 여기서 시작.
};

startInid 옵션은 Chrome 91에서 처음 도입되었습니다.

사용자 에이전트는 최근에 선택된 디렉터리 맵을 보유하며, 이는 origins에서 경로 id 맵으로의 맵입니다.

경로 id 맵 유효한 경로 id에서 경로로의 맵입니다.

유효한 경로 id는 각 문자가 ASCII 알파벳숫자 또는 "_" 또는 "-"인 문자열입니다.

경로 id 맵이 제한 없이 증가하는 것을 방지하기 위해 사용자 에이전트는 최근에 선택된 디렉터리가 기억되는 수를 제한하는 메커니즘을 구현해야 합니다. 이는 예를 들어 가장 최근에 사용되지 않은 항목을 제거하는 것으로 수행할 수 있습니다. 사용자 에이전트는 경로 id 맵에 최소 16개의 항목을 저장할 수 있도록 해야 합니다.

WellKnownDirectory 열거형은 웹사이트가 여러 잘 알려진 디렉터리 중 하나를 선택할 수 있도록 합니다. 이 열거형의 다양한 값이 매핑되는 정확한 경로는 implementation-defined 이며, 경우에 따라 디스크 상에 실제 경로를 나타내지 않을 수도 있습니다. 다음 목록은 각 값의 의미를 설명하며, 다른 운영 체제에서 가능한 예제 경로를 제공합니다:

"desktop"

사용자의 데스크톱 디렉터리(존재한다면). 예를 들어 C:\Documents and Settings\username\Desktop, /Users/username/Desktop, 또는 /home/username/Desktop가 될 수 있습니다.

"documents"

사용자가 만든 문서가 일반적으로 저장되는 디렉터리. 예를 들어 C:\Documents and Settings\username\My Documents, /Users/username/Documents, 또는 /home/username/Documents.

"downloads"

다운로드된 파일이 일반적으로 저장되는 디렉터리. 예를 들어 C:\Documents and Settings\username\Downloads, /Users/username/Downloads, 또는 /home/username/Downloads.

"music"

오디오 파일이 일반적으로 저장되는 디렉터리. 예를 들어 C:\Documents and Settings\username\My Documents\My Music, /Users/username/Music, 또는 /home/username/Music.

"pictures"

사진 및 기타 정지 이미지가 일반적으로 저장되는 디렉터리. 예를 들어 C:\Documents and Settings\username\My Documents\My Pictures, /Users/username/Pictures, 또는 /home/username/Pictures.

"videos"

비디오/영화가 일반적으로 저장되는 디렉터리. 예를 들어 C:\Documents and Settings\username\My Documents\My Videos, /Users/username/Movies, 또는 /home/username/Videos.

선택기가 시작할 디렉터리를 결정하려면, 선택적 문자열 id, 선택적 StartInDirectory startIn환경 설정 객체 environment가 주어지면 다음 단계를 실행합니다:
  1. id가 주어지고 유효한 경로 id가 아니면, TypeErrorthrow 합니다.

  2. id길이가 32보다 크면, TypeErrorthrow 합니다.

  3. originenvironmentorigin으로 둡니다.

  4. startInFileSystemHandle 이고 startIn버킷 파일 시스템에 있지 않은 경우:

    1. entrystartInlocator를 사용하여 항목을 찾는 결과로 둡니다.

    2. entry파일 항목이면, 로컬 파일 시스템에서 entry부모의 경로를 반환합니다.

    3. entry디렉터리 항목이면, 로컬 파일 시스템에서 entry의 경로를 반환합니다.

  5. id가 비어 있지 않으면:

    1. 최근에 선택된 디렉터리 맵[origin] 존재하면:

      1. path map최근에 선택된 디렉터리 맵[origin]으로 둡니다.

      2. path map[id] 존재하면 path map[id]를 반환합니다.

  6. startInWellKnownDirectory 이면:

    1. startInWellKnownDirectory 값에 해당하는 사용자 에이전트 정의 경로를 반환합니다.

  7. id가 지정되지 않았거나 빈 문자열이면:

    1. 최근에 선택된 디렉터리 맵[origin] 존재하면:

      1. path map최근에 선택된 디렉터리 맵[origin]으로 둡니다.

      2. path map[""] 존재하면 path map[""]을 반환합니다.

  8. 사용자 에이전트 특정 방식으로 기본 경로를 반환합니다.

선택된 디렉터리를 기억하려면, 선택적 문자열 id, 파일 시스템 항목 entry환경 설정 객체 environment가 주어지면 다음 단계를 실행합니다:
  1. originenvironmentorigin으로 둡니다.

  2. 최근에 선택된 디렉터리 맵[origin]이 존재하지 않으면, 최근에 선택된 디렉터리 맵[origin]을 빈 경로 id 맵으로 설정합니다.

  3. id가 지정되지 않았으면 id를 빈 문자열로 둡니다.

  4. 최근에 선택된 디렉터리 맵[origin][id]를 로컬 파일 시스템에서 entry에 해당하는 경로로 설정합니다, 그러한 경로를 결정할 수 있는 경우.

3.3. showOpenFilePicker() 메서드

[ handle ] = await window . showOpenFilePicker()
[ handle ] = await window . showOpenFilePicker({ multiple: false })

사용자가 단일 기존 파일을 선택할 수 있도록 하는 파일 선택기를 표시하며, 선택된 파일에 대한 핸들을 반환합니다.

handles = await window . showOpenFilePicker({ multiple: true })

사용자가 여러 기존 파일을 선택할 수 있도록 하는 파일 선택기를 표시하며, 선택된 파일들에 대한 핸들을 반환합니다.

showOpenFilePicker() 에 추가 옵션을 전달하여 웹사이트가 사용자가 선택할 파일 유형과 파일 선택기가 열릴 디렉터리를 나타낼 수 있습니다. 자세한 내용은 § 3.2 File picker options를 참조하십시오.

showOpenFilePicker(options) 메서드는 호출되었을 때 다음 단계를 실행해야 합니다:
  1. environmentthis관련 설정 객체로 둡니다.

  2. accepts optionsoptions를 사용하여 수락 유형을 처리한 결과로 둡니다.

  3. starting directoryoptions["id"], options["startIn"], 및 environment를 사용하여 선택기가 시작할 디렉터리를 결정한 결과로 둡니다.

  4. globalenvironmentglobal object로 둡니다.

  5. environment파일 선택기를 표시할 수 있는지 확인합니다.

  6. p새로운 프라미스로 둡니다.

  7. 다음 단계를 병렬로 실행합니다:

    1. 선택적으로, 이 알고리즘의 이전 실행이 종료될 때까지 기다립니다.

    2. filePickerOptions를 빈 으로 둡니다.

    3. filePickerOptions["multiple"]을 options["multiple"]으로 설정합니다.

    4. dismissed를 null과 filePickerOptionsWebDriver BiDi 파일 대화 상자가 열린 결과로 둡니다.

    5. dismissed가 false이면:

      1. 사용자에게 파일을 선택하도록 요청하는 프롬프트를 표시합니다. filePickerOptions["multiple"]이 false이면 파일이 하나만 선택되어야 합니다; 그렇지 않으면 여러 개가 선택될 수 있습니다.

        표시된 프롬프트는 표시된 파일 목록을 필터링하기 위해 accepts options 중 하나를 선택할 수 있도록 해야 합니다. 정확히 어떻게 구현되며, 이 프롬프트가 어떻게 보이는지는 implementation-defined입니다.

        가능하다면 이 프롬프트는 starting directory를 표시하도록 시작해야 합니다.

      2. 사용자가 선택을 완료할 때까지 기다립니다.

    6. dismissed가 true이거나 사용자가 선택 없이 프롬프트를 닫았으면, p를 "AbortError" DOMException으로 reject 하고 중단합니다.

    7. entries를 선택된 파일 또는 디렉터리를 나타내는 목록파일 항목으로 둡니다.

    8. result를 빈 목록으로 둡니다.

    9. entries의 각 entry에 대해:

      1. entry가 사용자 에이전트에 의해 이 웹사이트에 노출되는 것이 너무 민감하거나 위험하다고 판단되면:

        1. 선택된 파일 또는 디렉터리가 이 웹사이트에 노출될 수 없다고 사용자에게 알립니다.

        2. 사용자 에이전트의 재량에 따라, 이 병렬 단계의 시작으로 돌아가거나 p를 "AbortError" DOMException으로 reject 하고 중단합니다.

      2. entry와 연관된 새 FileSystemFileHandleresult에 추가합니다.

    10. options["id"], entries[0] 및 environment를 사용하여 선택된 디렉터리를 기억합니다.

    11. global브라우징 컨텍스트에서 활성화 알림 단계를 수행합니다.

      참고: 이를 통해 웹사이트는 사용자 활성화를 요구할 수 있는 반환된 핸들에 대한 작업을 즉시 수행할 수 있습니다.

    12. presultresolve 합니다.

  8. p를 반환합니다.

3.4. showSaveFilePicker() 메서드

handle = await window . showSaveFilePicker( options )

사용자가 단일 파일을 선택할 수 있도록 하는 파일 선택기를 표시하며, 선택된 파일에 대한 핸들을 반환합니다. 선택된 파일이 이미 존재하지 않아도 됩니다. 선택된 파일이 존재하지 않으면 이 메서드가 반환되기 전에 새로운 빈 파일이 생성되며, 그렇지 않으면 기존 파일이 이 메서드가 반환되기 전에 지워집니다.

handle = await window . showSaveFilePicker({ suggestedName: "README.md" })

제안된 "README.md" 파일 이름을 기본 파일 이름으로 미리 채워진 파일 선택기를 표시합니다. 저장할 파일 이름으로.

showSaveFilePicker() 에 추가 options를 전달하여 웹사이트가 사용자가 선택할 파일 유형과 파일 선택기가 열릴 디렉터리를 나타낼 수 있습니다. 자세한 내용은 § 3.2 File picker options를 참조하십시오.

suggestedName 옵션은 Chrome 91에서 처음 도입되었습니다.

showSaveFilePicker(options) 메서드는 호출되었을 때 다음 단계를 실행해야 합니다:
  1. environmentthis관련 설정 객체로 둡니다.

  2. accepts optionsoptions를 사용하여 수락 유형을 처리한 결과로 둡니다.

  3. starting directoryoptions["id"], options["startIn"] 및 environment를 사용하여 선택기가 시작할 디렉터리를 결정한 결과로 둡니다.

  4. globalenvironmentglobal object로 둡니다.

  5. environment파일 선택기를 표시할 수 있는지 확인합니다.

  6. p새로운 프라미스로 둡니다.

  7. 다음 단계를 병렬로 실행합니다:

    1. 선택적으로, 이 알고리즘의 이전 실행이 종료될 때까지 기다립니다.

    2. 사용자에게 정확히 하나의 파일을 선택하도록 요청하는 프롬프트를 표시합니다. 표시된 프롬프트는 표시된 파일 목록을 필터링하기 위해 accepts options 중 하나를 선택할 수 있도록 해야 합니다. 이것이 어떻게 구현되고 이 프롬프트가 어떻게 보이는지는 implementation-defined입니다. accepts options가 UI에 표시되면 선택된 옵션도 사용자 제공 파일 이름에 추가할 확장자를 제안하는 데 사용되어야 하지만 필수 사항은 아닙니다. 특히 사용자 에이전트는 ".lnk" 또는 ".local"로 끝나는 것과 같은 잠재적으로 위험한 접미사를 무시할 수 있습니다.

      가능하다면 이 프롬프트는 starting directory를 표시하도록 시작해야 합니다.

      options["suggestedName"] 이 존재하고 null이 아니면, 파일 선택기 프롬프트는 options["suggestedName"] 을 기본 이름으로 미리 채워집니다. 저장할 파일 이름으로. suggestedNameaccepts options 간의 상호 작용은 implementation-defined입니다. suggestedName 이 너무 위험하다고 판단되면, 사용자 에이전트는 제안된 파일 이름을 무시하거나 정리해야 하며, 다운로드로 가져올 때 수행되는 정리와 유사합니다.

      참고: 사용자 에이전트는 예를 들어 accepts options에서 suggestedName 과 일치하는 옵션을 기본 필터로 선택할 수 있습니다.

    3. 사용자가 선택을 완료할 때까지 기다립니다.

    4. 사용자가 선택 없이 프롬프트를 닫았으면, p를 "AbortError" DOMException 으로 reject 하고 중단합니다.

    5. entry를 선택된 파일을 나타내는 파일 항목으로 둡니다.

    6. entry가 사용자 에이전트에 의해 이 웹사이트에 노출되는 것이 너무 민감하거나 위험하다고 판단되면:

      1. 사용자에게 선택된 파일 또는 디렉터리가 이 웹사이트에 노출될 수 없다고 알립니다.

      2. 사용자 에이전트의 재량에 따라, 이 병렬 단계의 시작으로 돌아가거나 p를 "AbortError" DOMException 으로 reject 하고 중단합니다.

    7. entry이진 데이터를 빈 바이트 시퀀스로 설정합니다.

    8. resultentry와 연관된 새로운 FileSystemFileHandle 로 설정합니다.

    9. options["id"], entryenvironment를 사용하여 선택된 디렉터리를 기억합니다.

    10. global브라우징 컨텍스트에서 활성화 알림 단계를 수행합니다.

      참고: 이를 통해 웹사이트는 사용자 활성화를 요구할 수 있는 반환된 핸들에 대한 작업을 즉시 수행할 수 있습니다.

    11. presultresolve 합니다.

  8. p를 반환합니다.

3.5. showDirectoryPicker() 메서드

handle = await window . showDirectoryPicker()
handle = await window . showDirectoryPicker()({ mode: 'read' })

사용자가 단일 디렉터리를 선택할 수 있도록 하는 디렉터리 선택기를 표시하며, 사용자가 읽기 권한을 부여하면 선택된 디렉터리에 대한 핸들을 반환합니다.

handle = await window . showDirectoryPicker()({ mode: 'readwrite' })

사용자가 단일 디렉터리를 선택할 수 있도록 하는 디렉터리 선택기를 표시하며, 선택된 디렉터리에 대한 핸들을 반환합니다. 사용자 에이전트는 이 핸들에 대한 읽기 및 쓰기 권한 요청을 하나의 후속 프롬프트로 결합할 수 있습니다.

idstartIn 필드는 각각 idstartIn 필드와 동일하게 작동합니다. 이러한 필드를 사용하는 방법에 대한 자세한 내용은 § 3.2.2 Starting Directory를 참조하십시오.

showDirectoryPicker(options) 메서드는 호출되었을 때 다음 단계를 실행해야 합니다:
  1. environmentthis관련 설정 객체로 둡니다.

  2. starting directoryoptions["id"], options["startIn"] 및 environment를 사용하여 선택기가 시작할 디렉터리를 결정한 결과로 둡니다.

  3. globalenvironmentglobal object로 둡니다.

  4. environment파일 선택기를 표시할 수 있는지 확인합니다.

  5. p새로운 프라미스로 둡니다.

  6. 다음 단계를 병렬로 실행합니다:

    1. 선택적으로, 이 알고리즘의 이전 실행이 종료될 때까지 기다립니다.

    2. filePickerOptions를 빈 으로 둡니다.

    3. filePickerOptions["multiple"]을 false로 설정합니다.

    4. dismissed를 null과 filePickerOptionsWebDriver BiDi 파일 대화 상자가 열린 결과로 둡니다.

    5. dismissed가 false이면:

      1. 사용자에게 디렉터리를 선택하도록 요청하는 프롬프트를 표시합니다.

        가능하다면 이 프롬프트는 starting directory를 표시하도록 시작해야 합니다.

      2. 사용자가 선택을 완료할 때까지 기다립니다.

    6. dismissed가 true이거나 사용자가 선택 없이 프롬프트를 닫았으면, p를 "AbortError" DOMException 으로 reject 하고 중단합니다.

    7. entry를 선택된 디렉터리를 나타내는 디렉터리 항목으로 둡니다.

    8. entry가 사용자 에이전트에 의해 이 웹사이트에 노출되는 것이 너무 민감하거나 위험하다고 판단되면:

      1. 사용자에게 선택된 파일 또는 디렉터리가 이 웹사이트에 노출될 수 없다고 알립니다.

      2. 사용자 에이전트의 재량에 따라, 이 병렬 단계의 시작으로 돌아가거나 p를 "AbortError" DOMException 으로 reject 하고 중단합니다.

    9. resultentry와 연관된 새로운 FileSystemDirectoryHandle 로 설정합니다.

    10. options["id"], entryenvironment를 사용하여 선택된 디렉터리를 기억합니다.

    11. descFileSystemPermissionDescriptor 로 둡니다.

    12. desc["name"] 을 "file-system" 으로 설정합니다.

    13. desc["handle"] 을 result로 설정합니다.

    14. desc["mode"] 을 options["mode"] 로 설정합니다.

    15. statusdesc에 대해 PermissionStatus를 생성한 결과로 둡니다.

    16. global브라우징 컨텍스트에서 활성화 알림 단계를 수행합니다.

    17. desc를 사용하기 위해 권한을 요청합니다.

    18. descstatus에 대해 기본 권한 쿼리 알고리즘을 실행합니다.

    19. status가 "granted" 가 아니면, result를 "AbortError" DOMException 으로 reject 하고 중단합니다.

    20. global브라우징 컨텍스트에서 활성화 알림 단계를 수행합니다.

    21. presultresolve 합니다.

  7. p를 반환합니다.

3.6. 드래그 앤 드롭

partial interface DataTransferItem {
    Promise<FileSystemHandle?> getAsFileSystemHandle();
};

드래그 앤 드롭 작업 중에 드래그된 파일 및 디렉터리 항목은 각각 파일 항목디렉터리 항목 과 연관됩니다.

handle = await item . getAsFileSystemHandle()

드래그된 항목이 파일이면 FileSystemFileHandle 객체를 반환하고 드래그된 항목이 디렉터리이면 FileSystemDirectoryHandle 객체를 반환합니다.

getAsFileSystemHandle() 메서드 단계는 다음과 같습니다:

  1. DataTransferItem 객체가 읽기/쓰기 모드 또는 읽기 전용 모드에 있지 않으면 null해결된 프라미스를 반환합니다.

  2. 드래그 데이터 항목 종류File이 아니면, null해결된 프라미스를 반환합니다.

  3. p새로운 프라미스로 둡니다.

  4. 다음 단계를 병렬로 실행합니다:

    1. entry를 드래그된 파일 또는 디렉터리를 나타내는 파일 시스템 항목으로 둡니다.

    2. entry파일 항목이면:

      1. handleentry와 연관된 FileSystemFileHandle 로 둡니다.

    3. 그렇지 않으면 entry디렉터리 항목이면:

      1. handleentry와 연관된 FileSystemDirectoryHandle 로 둡니다.

    4. pentryresolve 합니다.

  5. p를 반환합니다.

파일 및 디렉터리의 드래그 앤 드롭 처리:
elem.addEventListener('dragover', (e) => {
  // Prevent navigation.
  e.preventDefault();
});

elem.addEventListener('drop', async (e) => {
  e.preventDefault();

  const fileHandlesPromises = [...e.dataTransfer.items]
    .filter(item => item.kind === 'file')
    .map(item => item.getAsFileSystemHandle());

  for await (const handle of fileHandlesPromises) {
    if (handle.kind === 'directory') {
      console.log(`Directory: ${handle.name}`);
    } else {
      console.log(`File: ${handle.name}`);
    }
  }
});

이것은 현재 드롭된 파일 및 디렉터리에 대한 액세스를 제공하는 다른 API와 일관성을 위해 너무 민감하거나 위험한 디렉터리에 대한 액세스를 차단하지 않습니다. 그러나 이는 로컬 파일 시스템 핸들 생성기와 일관되지 않으므로 이를 재고할 수 있습니다.

4. 접근성 고려 사항

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

이 규격이 사용자 인터페이스에 정보를 표시할 때, 구현자는 플랫폼의 OS 수준 접근성 지침을 따르기를 원할 것입니다.

5. 개인정보 보호 고려 사항

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

이 API는 기존 <input type=file><input type=file webkitdirectory> API가 이미 하는 것보다 웹사이트에 데이터에 대한 더 많은 읽기 액세스를 제공하지 않습니다. 더욱이 이 API와 유사하게 모든 파일 및 디렉터리에 대한 액세스는 파일 또는 디렉터리 선택기에 의해 명시적으로 게이트됩니다.

그러나 이 새로운 API에는 몇 가지 주요 개인정보 보호 위험이 있습니다:

5.1. 사용자가 의도한 것보다 더 많거나 더 민감한 파일에 대한 액세스를 부여하는 경우.

이것은 이 API의 새로운 위험이 아니지만, 사용자 에이전트는 사용자가 웹사이트에 액세스를 부여하는 것이 무엇인지 정확히 알도록 해야 합니다. 이는 특히 디렉터리에 대한 액세스를 부여할 때 중요하며, 사용자가 그 디렉터리에 실제로 얼마나 많은 파일이 존재하는지 즉시 명확하지 않을 수 있습니다.

관련 위험은 특히 민감한 데이터에 대한 액세스입니다. 이는 사용자 에이전트의 구성 데이터, 네트워크 캐시 또는 쿠키 저장소, 또는 비밀번호 파일과 같은 운영 체제 구성 데이터와 같은 것을 포함할 수 있습니다. 이를 보호하기 위해 사용자 에이전트는 디렉터리 선택기에서 사용자가 선택할 수 있는 디렉터리를 제한하는 것이 권장되며, 잠재적으로 파일 선택기에서 사용자가 선택할 수 있는 파일도 제한합니다. 이렇게 하면 특히 민감한 데이터를 포함하는 디렉터리에 실수로 액세스하는 것을 훨씬 어렵게 만들 수 있습니다. 이 API가 유용하도록 액세스를 제한하면서 민감한 데이터를 포함할 수 있는 디렉터리를 제한하는 올바른 균형을 유지해야 합니다. 결국, 이 API는 사용자가 가장 개인적인 데이터를 웹사이트와 상호 작용할 수 있도록 의도적으로 허용합니다.

사용자 에이전트가 제한해야 할 수 있는 디렉터리의 예는 다음과 같습니다:

5.2. 웹사이트가 이 API를 사용하여 사용자를 추적하려는 경우.

이 API는 브라우징 데이터를 지우는 것을 통해 사용자를 추적하는 데 사용할 수 있습니다. 이는 기존 파일 액세스 API와 달리 사용자 에이전트가 파일이나 디렉터리에 대한 영구 액세스를 부여할 수 있고 재프롬프트할 수 있기 때문입니다. 파일에 쓰기 기능을 결합하면 웹사이트는 사용자의 디스크에 식별자를 영구적으로 저장할 수 있습니다. 브라우징 데이터를 지워도 이러한 파일에는 영향을 미치지 않으므로 이러한 식별자는 이러한 작업을 통해 유지됩니다.

이 위험은 브라우징 데이터를 지우면 웹사이트가 유지한 모든 핸들이 지워진다는 사실로 어느 정도 완화됩니다 (예: IndexedDB에 유지됨), 따라서 브라우징 데이터가 지워진 후 웹사이트는 권한을 재요청할 핸들을 갖지 않습니다. 더욱이 사용자 에이전트는 웹사이트가 액세스할 수 있는 파일 및 디렉터리가 무엇인지 명확히 하고, 특히 신뢰할 수 있는 출처(예: "설치된" 웹 애플리케이션으로 제한된 영구 권한)에 대해 권한 부여를 자동으로 만료하도록 권장됩니다.

사용자 에이전트는 또한 사용자가 부여한 권한을 취소할 수 있는 방법을 제공하는 것이 권장됩니다. 브라우징 데이터를 지우면 모든 권한이 취소되는 것으로 예상됩니다.

5.3. 자사 대 제3자 컨텍스트.

제3자 컨텍스트에서(예: iframe이 최상위 프레임의 출처와 일치하지 않음) 웹사이트는 이미 액세스할 수 있는 데이터를 초과하는 데이터에 액세스할 수 없습니다. 여기에는 로컬 파일 시스템 핸들 생성기를 통해 새 파일 또는 디렉터리에 액세스하는 것과 기존 핸들에 대한 더 많은 권한을 요청하는 requestPermission API가 포함됩니다.

핸들은 동일 출처 목적지로만 메시지 전송될 수 있습니다. 핸들을 크로스-출처 목적지로 보내려고 시도하면 messageerror 이벤트가 발생합니다.

6. 보안 고려 사항

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

이 API는 디스크의 기존 파일을 수정하고 새 파일에 쓰는 웹사이트의 능력을 제공합니다. 이는 몇 가지 중요한 보안 고려 사항이 있습니다:

6.1. 맬웨어

이 API는 웹사이트가 사용자의 시스템에 맬웨어를 저장하거나 실행하려고 시도할 수 있습니다. 이 위험을 완화하기 위해 이 API는 파일을 실행 가능으로 표시할 수 있는 방법을 제공하지 않습니다 (다른 한편으로 이미 실행 가능한 파일은 이 API를 통해 수정된 후에도 여전히 실행 가능할 수 있지만). 더욱이 사용자 에이전트는 이 API에 의해 생성되거나 수정된 파일에 Mark-of-the-Web과 같은 것을 적용하는 것이 권장됩니다.

마지막으로, 사용자 에이전트는 이 API에 의해 수정된 파일의 콘텐츠를 맬웨어 스캔 및 안전 브라우징 검사를 통해 확인하는 것이 권장되며, 이미 강력한 외부 신뢰 관계가 존재하지 않는 한 그렇습니다. 물론 이는 이 API의 성능 특성에 영향을 미칩니다.

6.2. 랜섬웨어 공격

또 다른 위험 요소는 랜섬웨어 공격입니다. 위에서 설명한 민감한 디렉터리에 대한 액세스를 차단하는 제한은 그러한 공격이 할 수 있는 피해를 제한합니다. 또한 사용자 에이전트는 파일에 대한 쓰기 액세스를 적절하다고 판단하는 세분성으로 부여할 수 있습니다.

6.3. 사용자의 디스크 채우기

버킷 파일 시스템의 파일을 제외하고 이 API에 의해 작성된 파일은 저장소 할당량의 적용을 받지 않습니다. 따라서 웹사이트는 할당량에 의해 제한되지 않고 사용자의 디스크를 채울 수 있습니다 (큰 파일을 다운로드하는 것을 트리거하여 클라이언트 측에서 생성된 잠재적으로 큰 파일을 생성하더라도 할당량이 관리되는 저장소에서도 여전히 가능하지만, 저장소 할당량은 일반적으로 사용 가능한 디스크 공간의 양에 따라 달라지지 않습니다).

이 API 없이 웹사이트는 할당량 제한의 적용을 받지 않는 디스크에 데이터를 쓸 수 있습니다. 큰 파일을 다운로드하는 것을 트리거하여 (잠재적으로 클라이언트 측에서 생성된, 네트워크 오버헤드를 유발하지 않음). truncate() 의 존재와 파일 끝을 지나 큰 오프셋으로 쓰는 것은 훨씬 쉽고 낮은 비용으로 큰 파일을 생성합니다. 그러나 대부분의 파일 시스템은 희소 파일을 지원하므로 실제로 그러한 파일이 디스크 공간을 많이 차지하지 않을 수 있습니다 (일반적으로 사용되는 파일 시스템의 대부분은 파일 크기를 조정하거나 파일 끝을 지나 찾는 데 의해 생성된 NUL 바이트를 실제로 저장하지 않습니다).

어떤 완화 조치가 할당량 관리 저장소나 기존 다운로드 메커니즘을 통해 웹사이트가 디스크를 채우는 것을 방지하기 위해 사용자 에이전트가 사용하는지, 웹사이트가 이 API를 사용하여 디스크에 쓸 때도 동일하게 적용해야 합니다.

준수

문서 규칙

준수 요구 사항은 설명적 주장과 RFC 2119 용어의 조합으로 표현됩니다. 이 규범적 부분의 주요 단어 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 및 "OPTIONAL" 은 RFC 2119에 설명된 대로 해석됩니다. 그러나 가독성을 위해, 이 규격에서는 이러한 단어가 모두 대문자로 나타나지 않습니다.

이 규격의 모든 텍스트는 규범적 섹션으로 표시된 섹션, 예제 및 참고 사항을 제외하고 규범적입니다. [RFC2119]

이 규격의 예제는 "for example" 또는 규범적 텍스트에서 분리된 class="example"로 소개됩니다, 다음과 같습니다:

이것은 정보적 예제의 예입니다.

정보적 참고 사항은 "Note" 단어로 시작하며 규범적 텍스트에서 분리된 class="note"로 설정됩니다, 다음과 같습니다:

참고, 이것은 정보적 참고입니다.

색인

이 규격에서 정의된 용어

참조로 정의된 용어

참조

규범적 참조

[FS]
Austin Sullivan. 파일 시스템 표준. 라이브 표준. URL: https://fs.spec.whatwg.org/
[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/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing 표준. 라이브 표준. URL: https://mimesniff.spec.whatwg.org/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. 권한. URL: https://w3c.github.io/permissions/
[PERMISSIONS-REQUEST]
권한 요청. 초안 커뮤니티 그룹 보고서. URL: https://wicg.github.io/permissions-request/
[RFC2119]
S. Bradner. RFCs에서 요구 사항 수준을 나타내는 키워드. 1997년 3월. 최선의 현재 실천. URL: https://datatracker.ietf.org/doc/html/rfc2119
[STORAGE]
Anne van Kesteren. 저장소 표준. 라이브 표준. URL: https://storage.spec.whatwg.org/
[WEBDRIVER-BIDI]
James Graham; Alex Rudenko; Maksim Sadym. WebDriver BiDi. URL: https://w3c.github.io/webdriver-bidi/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 표준. 라이브 표준. URL: https://webidl.spec.whatwg.org/

정보적 참조

[ENTRIES-API]
파일 및 디렉터리 항목 API. 초안 커뮤니티 그룹 보고서. URL: https://wicg.github.io/entries-api/
[FILE-API]
Marijn Kruisselbrink. 파일 API. URL: https://w3c.github.io/FileAPI/

IDL 색인

enum FileSystemPermissionMode {
  "read",
  "readwrite"
};

dictionary FileSystemPermissionDescriptor : PermissionDescriptor {
  required FileSystemHandle handle;
  FileSystemPermissionMode mode = "read";
};

dictionary FileSystemHandlePermissionDescriptor {
  FileSystemPermissionMode mode = "read";
};

[Exposed=(Window,Worker), SecureContext, Serializable]
partial interface FileSystemHandle {
  Promise<PermissionState> queryPermission(optional FileSystemHandlePermissionDescriptor descriptor = {});
  Promise<PermissionState> requestPermission(optional FileSystemHandlePermissionDescriptor descriptor = {});
};

enum WellKnownDirectory {
  "desktop",
  "documents",
  "downloads",
  "music",
  "pictures",
  "videos",
};

typedef (WellKnownDirectory or FileSystemHandle) StartInDirectory;

dictionary FilePickerAcceptType {
    USVString description = "";
    record<USVString, (USVString or sequence<USVString>)> accept;
};

dictionary FilePickerOptions {
    sequence<FilePickerAcceptType> types;
    boolean excludeAcceptAllOption = false;
    DOMString id;
    StartInDirectory startIn;
};

dictionary OpenFilePickerOptions : FilePickerOptions {
    boolean multiple = false;
};

dictionary SaveFilePickerOptions : FilePickerOptions {
    USVString? suggestedName;
};

dictionary DirectoryPickerOptions {
    DOMString id;
    StartInDirectory startIn;
    FileSystemPermissionMode mode = "read";
};

[SecureContext]
partial interface Window {
    Promise<sequence<FileSystemFileHandle>> showOpenFilePicker(optional OpenFilePickerOptions options = {});
    Promise<FileSystemFileHandle> showSaveFilePicker(optional SaveFilePickerOptions options = {});
    Promise<FileSystemDirectoryHandle> showDirectoryPicker(optional DirectoryPickerOptions options = {});
};

partial interface DataTransferItem {
    Promise<FileSystemHandle?> getAsFileSystemHandle();
};

이슈 색인

이 검사를 항목과 더 이상 연관되지 않게 만드십시오. [whatwg/fs Issue #101]
이상적으로 이 사용자 활성화 요구 사항은 업스트림에서 정의되어야 합니다. [WICG/permissions-request Issue #2]
현재 FileSystemPermissionMode 는 "read" 또는 "readwrite" 일 수만 있습니다. 미래에 쓰기 전용 핸들을 지원하기 위해 "write" 모드도 추가하고 싶을 수 있습니다. [Issue #119]
이것은 현재 드롭된 파일 및 디렉터리에 대한 액세스를 제공하는 다른 API와 일관성을 위해 너무 민감하거나 위험한 디렉터리에 대한 액세스를 차단하지 않습니다. 그러나 이는 로컬 파일 시스템 핸들 생성기와 일관되지 않으므로 이를 재고할 수 있습니다.
MDN

DataTransferItem/getAsFileSystemHandle

In only one current engine.

FirefoxNoneSafariNoneChrome86+
Opera?Edge86+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for AndroidNoneAndroid WebView?Samsung Internet?Opera Mobile?
MDN

FileSystemHandle/queryPermission

In only one current engine.

FirefoxNoneSafariNoneChrome86+
Opera?Edge86+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebViewNoneSamsung Internet?Opera Mobile?
MDN

FileSystemHandle/requestPermission

In only one current engine.

FirefoxNoneSafariNoneChrome86+
Opera?Edge86+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebViewNoneSamsung Internet?Opera Mobile?
MDN

window/showdirectorypicker

In only one current engine.

FirefoxNoneSafariNoneChrome86+
Opera?Edge86+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for AndroidNoneAndroid WebView?Samsung Internet?Opera Mobile?
MDN

window/showopenfilepicker

In only one current engine.

FirefoxNoneSafariNoneChrome86+
Opera?Edge86+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for AndroidNoneAndroid WebView?Samsung Internet?Opera Mobile?
MDN

window/showsavefilepicker

In only one current engine.

FirefoxNoneSafariNoneChrome86+
Opera?Edge86+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for AndroidNoneAndroid WebView?Samsung Internet?Opera Mobile?