파일 API

W3C 워킹 드래프트,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2025/WD-FileAPI-20251203/
최신 공개 버전:
https://www.w3.org/TR/FileAPI/
에디터스 드래프트:
https://w3c.github.io/FileAPI/
이전 버전:
히스토리:
https://www.w3.org/standards/history/FileAPI/
피드백:
GitHub
명세 내 인라인
에디터:
(Google)
이전 에디터:
Arun Ranganathan (Mozilla Corporation)
테스트:
web-platform-tests FileAPI/ (진행 중인 작업)

개요

이 명세는 웹 애플리케이션에서 파일 객체를 표현하고, 이를 프로그래밍 방식으로 선택하거나 데이터에 접근할 수 있는 API를 제공합니다. 이에는 다음이 포함됩니다:

추가적으로, 이 명세는 파일의 동기적 읽기를 지원하기 위해 스레드 기반 웹 애플리케이션에서 사용할 객체도 정의합니다.

§ 10 요구 사항 및 활용 사례에서는 이 명세의 동기를 다룹니다.

이 API는 웹 플랫폼의 다른 API 및 요소들과 함께 사용되도록 설계되었습니다. 특히: XMLHttpRequest (예: send() 메서드가 File 또는 Blob 인자를 받을 수 있도록 오버로드됨), postMessage(), DataTransfer ([HTML]에서 정의된 드래그 앤 드롭 API의 일부) 및 웹 워커와 함께 사용할 수 있습니다. 또한, input 요소가 파일 업로드 상태일 때 파일 목록을 프로그래밍적으로 얻는 것도 가능합니다 [HTML]. 이러한 동작들은 관련 명세에서 정의됩니다.

이 문서의 상태

이 절은 문서가 발행된 시점의 상태를 설명합니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.

이 문서는 웹 애플리케이션 워킹 그룹에 의해 워킹 드래프트로, 권고안 절차를 사용하여 발행되었습니다. 워킹 드래프트로 발행되었다고 해서 W3C 및 회원사의 승인(endorsement)을 의미하지는 않습니다.

이것은 초안 문서이며 언제든지 다른 문서에 의해 업데이트되거나 대체되거나 폐기될 수 있습니다. 진행 중인 작업이 아닌 다른 용도로 이 문서를 인용하는 것은 적절하지 않습니다.

이 명세에 대한 이전 논의는 두 개의 다른 메일링 리스트에서 진행되었습니다: public-webapps@w3.org (archive) 및 public-webapi@w3.org (archive). 지속적인 논의는 public-webapps@w3.org 메일링 리스트에서 이루어집니다.

이 초안은 이전의 Last Call 워킹 드래프트에 이루어진 변경 사항으로 구성됩니다. 위에서 설명한 대로 의견은 public-webapi@w3.org로 보내 주십시오. W3C 위키에서 Last Call 피드백을 확인할 수 있습니다: https://www.w3.org/wiki/Webapps/LCWD-FileAPI-20130912

구현 보고서는 테스트 스위트로부터 자동으로 생성됩니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에 의해 작성되었습니다. W3C는 해당 그룹의 산출물과 관련하여 이루어진 특허 공개의 공개 목록을 관리합니다; 해당 페이지에는 특허 공개 방법에 대한 안내도 포함되어 있습니다. 개인이 필수 청구(Essential Claim(s))를 포함한다고 믿는 특허에 대해 실제로 알고 있는 경우, W3C 특허 정책 W3C의 6절에 따라 정보를 공개해야 합니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서의 적용을 받습니다.

1. 소개

이 섹션은 참고용입니다.

웹 애플리케이션은 사용자가 원격 서버로 업로드하거나 풍부한 웹 애플리케이션 내에서 다루고자 하는 파일을 포함하여, 가능한 한 다양한 범위의 사용자 입력을 다룰 수 있어야 합니다. 이 명세는 파일의 기본 표현, 파일 목록, 파일 접근 중 발생하는 오류, 그리고 프로그래밍 방식으로 파일을 읽는 방법을 정의합니다. 또한 이 명세는 "원시 데이터"를 나타내는 인터페이스도 정의하며, 이는 적합한 사용자 에이전트의 메인 스레드에서 비동기적으로 처리될 수 있습니다. 이 명세에서 정의된 인터페이스와 API는 웹 플랫폼에 노출된 다른 인터페이스 및 API와 함께 사용할 수 있습니다.

File 인터페이스는 일반적으로 기본 파일 시스템에서 얻은 파일 데이터를 나타내며, Blob 인터페이스 ("Binary Large Object" - 본래 Google Gears에서 웹 API에 도입된 명칭) 는 불변의 원시 데이터를 나타냅니다. File 또는 Blob 읽기는 메인 스레드에서 비동기적으로 처리되어야 하며, 스레드 기반 웹 애플리케이션에서는 선택적으로 동기 API를 사용할 수 있습니다. 파일을 비동기적으로 읽는 API는 사용자 에이전트의 메인 스레드가 블로킹되거나 UI가 "멈추는" 것을 방지합니다. 이 명세는 이벤트 모델 기반의 비동기 API를 정의하여 File 또는 Blob의 데이터를 읽고 접근할 수 있도록 합니다. FileReader 객체는 파일 데이터를 비동기적으로 읽을 수 있는 메서드를 제공하며, 이벤트 핸들러 콘텐츠 속성과 이벤트 발생을 통해 파일 데이터를 접근할 수 있습니다. 이벤트와 이벤트 핸들러를 사용함으로써 개별 코드 블록이 읽기 진행 상황(특히 원격 드라이브나 마운트된 드라이브 등, 파일 접근 성능이 로컬 드라이브와 다를 수 있는 경우) 및 파일 읽기 중 발생할 수 있는 오류 상황을 모니터링할 수 있습니다. 아래 예제가 이를 보여줍니다.

아래 예제에서는 서로 다른 코드 블록이 진행 상황, 오류, 성공 상황을 처리합니다.
function startRead() {
  // DOM을 통해 input 요소 얻기

  var file = document.getElementById('file').files[0];
  if(file){
    getAsText(file);
  }
}

function getAsText(readFile) {

  var reader = new FileReader();

  // 파일을 UTF-16으로 메모리에 읽기
  reader.readAsText(readFile, "UTF-16");

  // 진행 상황, 성공, 오류 처리
  reader.onprogress = updateProgress;
  reader.onload = loaded;
  reader.onerror = errorHandler;
}

function updateProgress(evt) {
  if (evt.lengthComputable) {
    // evt.loaded와 evt.total은 ProgressEvent 속성입니다
    var loaded = (evt.loaded / evt.total);
    if (loaded < 1) {
      // 진행 바 길이 증가
      // style.width = (loaded * 200) + "px";
    }
  }
}

function loaded(evt) {
  // 읽은 파일 데이터 얻기
  var fileString = evt.target.result;
  // UTF-16 파일 덤프 처리
  if(utils.regexp.isChinese(fileString)) {
    // 한자 + 이름 검증
  }
  else {
    // 다른 문자셋 테스트 실행
  }
  // xhr.send(fileString)
}

function errorHandler(evt) {
  if(evt.target.error.name == "NotReadableError") {
    // 파일을 읽을 수 없음
  }
}

2. 용어 및 알고리즘

이 명세에서 알고리즘을 종료한다라고 할 때, 사용자 에이전트는 현재 수행 중인 단계를 마친 후 알고리즘을 종료해야 합니다. 이 명세에서 정의된 비동기 읽기 메서드는 해당 알고리즘이 종료되기 전에 반환될 수 있으며, abort() 호출로 종료될 수 있습니다.

이 명세의 알고리즘과 단계에서는 다음 수학 연산을 사용합니다:

Unix Epoch 용어는 이 명세에서 1970년 1월 1일 00:00:00 UTC (또는 1970-01-01T00:00:00Z, ISO 8601)를 가리키며, ECMA-262 [ECMA-262]에서 개념적으로 "0"에 해당하는 시간입니다.

slice blob 알고리즘은 Blob blob, start, end, contentType을 받아 다음과 같은 단계를 수행하며, start부터 end 이전까지의 바이트를 포함하는 새로운 Blob을 반환합니다. 동작 방식은 다음과 같습니다:
  1. originalSizeblobsize로 한다.

  2. start 매개변수가 null이 아니라면, slice blob 호출의 시작 위치 값으로 사용되며, 바이트 순서 위치로 처리해야 하며, 0번째 위치가 첫 바이트를 나타냅니다. 사용자 에이전트는 start를 다음과 같이 정규화해야 합니다:

    1. start가 null이면, relativeStart를 0으로 한다.
    2. start가 음수이면, relativeStartmax((originalSize + start), 0)으로 한다.
    3. 그 외에는, relativeStartmin(start, originalSize)으로 한다.
  3. end 매개변수가 null이 아니라면, slice blob 호출의 종료 위치 값으로 사용됩니다. 사용자 에이전트는 end를 다음과 같이 정규화해야 합니다:

    1. end가 null이면, relativeEndoriginalSize로 한다.
    2. end가 음수이면, relativeEndmax((originalSize + end), 0)으로 한다.
    3. 그 외에는, relativeEndmin(end, originalSize)으로 한다.
  4. contentType 매개변수가 null이 아니라면, Blob의 미디어 타입을 나타내는 소문자 ASCII 인코딩 문자열로 설정합니다. 사용자 에이전트는 contentType을 다음과 같이 정규화해야 합니다:

    1. contentType이 null이면, relativeContentType을 빈 문자열로 설정한다.
    2. 그렇지 않으면, relativeContentTypecontentType으로 설정하고, 다음 하위 단계를 실행한다:
      1. relativeContentType에 U+0020에서 U+007E 범위를 벗어나는 문자가 있으면, relativeContentType을 빈 문자열로 설정하고 이 하위 단계를 종료한다.

      2. relativeContentType의 모든 문자를 ASCII 소문자로 변환한다.

  5. spanmax((relativeEnd - relativeStart), 0)으로 한다.

  6. 다음 특성을 가진 새로운 Blob 객체 S를 반환한다:

    1. Sblob의 연결된 byte 시퀀스에서 relativeStart 바이트 순서 위치에서 시작하는 span 연속 byte를 참조한다.
    2. S.size = span.
    3. S.type = relativeContentType.

3. Blob 인터페이스와 바이너리 데이터

Blob 객체는 바이트 시퀀스를 참조합니다. size 속성은 바이트 시퀀스의 전체 바이트 수를 나타내며, type 속성은 바이트 시퀀스의 미디어 타입을 나타내는 소문자 ASCII 인코딩 문자열입니다.

Blob은 내부적으로 스냅샷 상태를 가져야 하며, 해당 기저 저장소가 존재한다면 그 저장소의 상태로 최초 설정되어야 합니다. 스냅샷 상태에 대한 추가 규범적 정의는 File에서 찾아볼 수 있습니다.

[Exposed=(Window,Worker), Serializable]
interface Blob {
  constructor(optional sequence<BlobPart> blobParts,
              optional BlobPropertyBag options = {});

  readonly attribute unsigned long long size;
  readonly attribute DOMString type;

  // slice Blob into byte-ranged chunks
  Blob slice(optional [Clamp] long long start,
            optional [Clamp] long long end,
            optional DOMString contentType);

  // read from the Blob.
  [NewObject] ReadableStream stream();
  [NewObject] Promise<USVString> text();
  [NewObject] Promise<ArrayBuffer> arrayBuffer();
  [NewObject] Promise<Uint8Array> bytes();
};

enum EndingType { "transparent", "native" };

dictionary BlobPropertyBag {
  DOMString type = "";
  EndingType endings = "transparent";
};

typedef (BufferSource or Blob or USVString) BlobPart;

Blob 객체는 직렬화 가능한 객체입니다. 직렬화 단계value, serialized가 주어졌을 때 다음과 같습니다:

  1. serialized.[[SnapshotState]]를 value스냅샷 상태로 설정합니다.

  2. serialized.[[ByteSequence]]를 value의 기저 바이트 시퀀스로 설정합니다.

역직렬화 단계serialized, value가 주어졌을 때 다음과 같습니다:

  1. value스냅샷 상태serialized.[[SnapshotState]]로 설정합니다.

  2. value의 기저 바이트 시퀀스를 serialized.[[ByteSequence]]로 설정합니다.

Blob blob에는 get stream 알고리즘이 연결되어 있으며, 다음 단계를 실행합니다:
  1. streamblob관련 Realm에서 새로운 ReadableStream으로 생성합니다.

  2. 바이트 읽기 지원으로 stream을 설정합니다.

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

    1. blob의 모든 바이트가 읽힐 때까지 반복:

      1. bytesblob에서 청크를 읽어 얻은 바이트 시퀀스로 설정하거나, 청크를 읽을 수 없다면 실패로 설정합니다.

      2. 글로벌 태스크 대기열에 추가blob파일 읽기 태스크 소스관련 글로벌 객체에 대해 다음 단계를 실행하는 작업으로 수행합니다:

        1. bytes가 실패라면, 실패 이유stream에 에러를 발생시키고 이 단계를 중단합니다.

        2. chunkbytes를 담은 ArrayBuffer를 감싼 새로운 Uint8Array로 할당합니다. ArrayBuffer 생성 시 예외가 발생하면, 그 예외로 stream에 에러를 발생시키고 이 단계를 중단합니다.

        3. chunkstreamenqueue합니다.

      Blob에서 실제로 읽는 동작, 발생할 수 있는 오류, 청크 크기 등 구체적으로 더 명확히 지정할 필요가 있습니다.

  4. stream을 반환합니다.

3.1. 생성자

Blob() 생성자는 0개 이상의 매개변수로 호출될 수 있습니다. Blob() 생성자가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:
  1. 만약 매개변수가 없이 호출된 경우, 0 바이트로 구성된 새로운 Blob 객체를 반환합니다. size는 0으로, type은 빈 문자열로 설정됩니다.

  2. bytesblobPartsoptions를 주어 blob parts 처리의 결과로 설정합니다.

  3. type 멤버가 options 인자에 빈 문자열이 아니라면, 다음 하위 단계를 실행합니다:

    1. ttype 딕셔너리 멤버로 설정합니다. t에 U+0020~U+007E 범위를 벗어나는 문자가 있으면, t를 빈 문자열로 설정하고 이 하위 단계에서 반환합니다.

    2. t의 모든 문자를 ASCII 소문자로 변환합니다.

  4. 위의 하위 단계의 t 값을 type으로 설정하고, bytes를 연결된 byte 시퀀스로 참조하는 Blob 객체를 반환합니다. sizebytes의 길이로 설정합니다.

3.1.1. 생성자 매개변수

Blob() 생성자는 아래의 매개변수들로 호출될 수 있습니다:

blobParts sequence
다음 타입의 요소들을 아무 순서로든 여러 개 받을 수 있습니다:
선택적 BlobPropertyBag
다음 선택 멤버를 받을 수 있습니다:
blob parts 처리BlobPart 시퀀스 partsBlobPropertyBag options를 받아 다음 단계를 실행합니다:
  1. bytes를 빈 바이트 시퀀스로 설정합니다.

  2. parts의 각 element에 대해:

    1. elementUSVString이면, 다음 하위 단계를 실행합니다:

      1. selement로 설정합니다.

      2. optionsendings 멤버가 "native"이면, selement줄 끝을 native로 변환의 결과로 설정합니다.

      3. sUTF-8 인코딩한 결과를 bytes에 추가합니다.

        참고: WebIDL [WebIDL]의 알고리즘은 잘못된 utf-16 문자열의 일치하지 않는 서러게이트를 U+FFFD 대체 문자로 바꿉니다. Blob 생성자는 문자 손실 또는 변형이 발생할 수 있습니다.

    2. elementBufferSource이면, 버퍼 소스의 바이트 복사본 얻기 후 해당 바이트를 bytes에 추가합니다.

    3. elementBlob이면, 해당 바이트를 bytes에 추가합니다.

      참고: Blob 배열 요소의 type은 무시되며 반환되는 Blob 객체의 type에 영향을 주지 않습니다.

  3. bytes를 반환합니다.

줄 끝을 native로 변환문자열 s에 대해 다음 단계를 실행합니다:
  1. native line ending코드 포인트 U+000A LF로 설정합니다.

  2. 기저 플랫폼이 줄 바꿈을 캐리지 리턴 + 라인 피드 시퀀스로 표현한다면, native line ending코드 포인트 U+000D CR과 이어지는 코드 포인트 U+000A LF로 설정합니다.

  3. result를 빈 문자열로 설정합니다.

  4. positions위치 변수로, s의 시작을 가리키도록 설정합니다.

  5. tokens에서 position을 주어 U+000A LF 또는 U+000D CR이 아닌 코드 포인트 시퀀스 수집의 결과로 설정합니다.

  6. tokenresult에 추가합니다.

  7. positions의 끝을 지나지 않은 동안:

    1. sposition에서 코드 포인트가 U+000D CR이면:

      1. native line endingresult에 추가합니다.

      2. position을 1만큼 이동합니다.

      3. positions의 끝을 지나지 않았고 sposition에서 코드 포인트가 U+000A LF이면, position을 1만큼 이동합니다.

    2. 그 외에 sposition에서 코드 포인트가 U+000A LF라면, position을 1만큼 이동하고 native line endingresult에 추가합니다.

    3. tokensposition에서 U+000A LF 또는 U+000D CR이 아닌 코드 포인트 시퀀스 수집의 결과로 설정합니다.

    4. tokenresult에 추가합니다.

  8. result를 반환합니다.

생성자 사용 예시는 다음과 같습니다.
// 새 Blob 객체 생성

var a = new Blob();

// 1024바이트 ArrayBuffer 생성
// buffer는 File을 읽어서도 얻을 수 있음

var buffer = new ArrayBuffer(1024);

// buffer로 ArrayBufferView 객체 생성

var shorts = new Uint16Array(buffer, 512, 128);
var bytes = new Uint8Array(buffer, shorts.byteOffset + shorts.byteLength);

var b = new Blob(["foobarbazetcetc" + "birdiebirdieboo"], {type: "text/plain;charset=utf-8"});

var c = new Blob([b, shorts]);

var a = new Blob([b, c, bytes]);

var d = new Blob([buffer, b, c, bytes]);

3.2. 속성

size, 타입 unsigned long long, 읽기 전용
바이트 시퀀스의 크기를 바이트 수로 반환합니다. 가져올 때, 적합한 사용자 에이전트는 FileReader 또는 FileReaderSync 객체로 읽을 수 있는 총 바이트 수를 반환해야 하며, Blob에 읽을 바이트가 없으면 0을 반환해야 합니다.
type, 타입 DOMString, 읽기 전용
Blob의 미디어 타입을 나타내는 소문자 ASCII 인코딩 문자열입니다. 가져올 때, 사용자 에이전트는 Blob의 타입을 소문자 ASCII 인코딩 문자열로 반환해야 하며, 바이트 시퀀스로 변환되었을 때 파싱 가능한 MIME 타입이어야 합니다. 타입을 결정할 수 없는 경우에는 빈 문자열(0 바이트)을 반환해야 합니다.

type 속성은 웹 애플리케이션에서 생성자 호출이나 slice() 호출을 통해 직접 설정할 수 있습니다. 이 경우, 이 속성에 대한 추가 규범 조건은 § 3.1 생성자, § 4.1 생성자, 그리고 § 3.3.1 slice() 메서드에 각각 정의되어 있습니다. 사용자 에이전트는 또한 바이트 시퀀스가 디스크 파일에서 얻어진 경우 등 Blob의 타입을 자체적으로 결정할 수도 있습니다. 이 경우에는 파일 타입 가이드라인에 추가 규범 조건이 있습니다.

참고: Blob의 타입 t파싱 가능한 MIME 타입으로 간주됩니다. 만약 Blob 객체의 타입을 나타내는 ASCII 인코딩 문자열을 바이트 시퀀스로 변환해 MIME 타입 파싱 알고리즘을 수행했을 때 실패를 반환하지 않으면 파싱 가능한 타입입니다.

참고: type 속성의 사용은 패키지 데이터 알고리즘에 영향을 주며, fetch를 통해 blob URL을 가져올 때 Content-Type 헤더를 결정합니다.

3.3. 메서드 및 매개변수

3.3.1. slice() 메서드

slice() 메서드는 선택적 start 매개변수부터 선택적 end 매개변수 이전까지의 바이트와, 선택적 contentType 값으로 type 속성을 가진 새로운 Blob 객체를 반환합니다. 동작은 다음과 같습니다:
  1. sliceStart, sliceEnd, sliceContentType을 null로 설정합니다.

  2. start가 주어지면 sliceStartstart로 설정합니다.

  3. end가 주어지면 sliceEndend로 설정합니다.

  4. contentType가 주어지면 sliceContentTypecontentType으로 설정합니다.

  5. slice blob 알고리즘의 결과를 this, sliceStart, sliceEnd, sliceContentType을 주어 반환합니다.

아래 예제는 slice() 호출의 다양한 유형을 보여줍니다. File 인터페이스가 Blob 인터페이스를 상속하므로, File 인터페이스 사용 예시입니다.
// DOM을 통해 input 요소 얻기

var file = document.getElementById('file').files[0];
if(file)
{
  // 파일의 동일한 복사본 생성
  // 아래 두 호출은 동일함

  var fileClone = file.slice();
  var fileClone2 = file.slice(0, file.size);

  // 파일의 중간부터 1/2 청크로 슬라이스 (음수 사용)
  var fileChunkFromEnd = file.slice(-(Math.round(file.size/2)));

  // 파일의 시작부터 1/2 청크로 슬라이스

  var fileChunkFromStart = file.slice(0, Math.round(file.size/2));

  // 파일의 시작부터 끝에서 150 바이트 전까지 슬라이스

  var fileNoMetadata = file.slice(0, -150, "application/experimental");
}

3.3.2. stream() 메서드

stream() 메서드는 호출 시 get streamthis에 대해 호출한 결과를 반환해야 합니다.

3.3.3. text() 메서드

text() 메서드는 호출 시 다음 단계를 실행해야 합니다:

  1. streamget streamthis에 대해 호출한 결과로 설정합니다.

  2. readerstream에서 reader 얻기의 결과로 설정합니다. 만약 예외가 발생하면, 해당 예외로 거부된 새로운 프라미스를 반환합니다.

  3. promisereader와 함께 stream에서 모든 바이트 읽기의 결과로 설정합니다.

  4. promise를 UTF-8로 디코드(UTF-8 decode)한 결과를 반환하는 이행 핸들러로 변환한 결과를 반환합니다.

참고: 이 동작은 readAsText()의 동작과 다르며, Fetch의 text()와 더 잘 맞추기 위한 것입니다. 이 메서드는 항상 UTF-8 인코딩을 사용하며, FileReader는 blob의 type과 전달된 인코딩 이름에 따라 다른 인코딩을 사용할 수 있습니다.

3.3.4. arrayBuffer() 메서드

arrayBuffer() 메서드는 호출될 때 다음 단계를 실행해야 합니다:

  1. streamget streamthis에 대해 호출한 결과로 설정합니다.

  2. readerstream에서 reader 얻기의 결과로 설정합니다. 예외가 발생하면, 해당 예외로 거부된 새로운 프라미스를 반환합니다.

  3. promisereader와 함께 stream에서 모든 바이트 읽기의 결과로 설정합니다.

  4. promise를 이행 핸들러로 변환한 결과를 반환하는데, 이 핸들러는 첫 번째 인자를 내용으로 하는 ArrayBuffer의 새 객체를 반환합니다.

3.3.5. bytes() 메서드

bytes() 메서드는 호출될 때 다음 단계를 실행해야 합니다:

  1. streamget streamthis에 대해 호출한 결과로 설정합니다.

  2. readerstream에서 reader 얻기의 결과로 설정합니다. 예외가 발생하면, 해당 예외로 거부된 새로운 프라미스를 반환합니다.

  3. promisereader와 함께 stream에서 모든 바이트 읽기의 결과로 설정합니다.

  4. promise를 이행 핸들러로 변환한 결과를 반환하는데, 이 핸들러는 첫 번째 인자를 내용으로 하는 Uint8Array의 새 객체를 반환하고, 그 객체는 ArrayBuffer를 감쌉니다.

4. File 인터페이스

File 객체는 Blob 객체로, 문자열 타입의 name 속성을 가집니다. 이 객체는 웹 애플리케이션 내에서 생성자를 통해 만들 수도 있고, 또는 기본(운영체제) 파일 시스템의 파일에서 가져온 바이트 시퀀스의 참조일 수도 있습니다.

File 객체가 디스크의 파일에서 유래된 바이트 시퀀스를 참조하는 경우, 그 스냅샷 상태File 객체가 생성된 시점의 디스크 파일 상태로 설정되어야 합니다.

참고: 이는 사용자 에이전트에게 구현 난이도가 있으므로 must가 아닌 should 요구사항입니다 [RFC2119]. 사용자 에이전트는 File 객체의 스냅샷 상태를 참조가 생성된 시점의 디스크 저장소 상태로 맞추도록 노력해야 합니다. 만약 파일이 참조 후 디스크에서 수정되면, File스냅샷 상태는 실제 저장소 상태와 다를 수 있습니다. 사용자 에이전트는 수정 시간 정보 등 다양한 방법으로 스냅샷 상태를 관리할 수 있지만, 이것은 구현 세부 사항에 속합니다.

File 객체가 디스크의 파일을 참조할 때, 사용자 에이전트는 해당 파일의 type을 반환해야 하며, 아래 파일 타입 가이드라인을 따라야 합니다:

[Exposed=(Window,Worker), Serializable]
interface File : Blob {
  constructor(sequence<BlobPart> fileBits,
              USVString fileName,
              optional FilePropertyBag options = {});
  readonly attribute DOMString name;
  readonly attribute long long lastModified;
};

dictionary FilePropertyBag : BlobPropertyBag {
  long long lastModified;
};

File 객체는 직렬화 가능한 객체입니다. 직렬화 단계valueserialized가 주어졌을 때 다음과 같습니다:

  1. serialized.[[SnapshotState]]를 value스냅샷 상태로 설정합니다.

  2. serialized.[[ByteSequence]]를 value의 기저 바이트 시퀀스로 설정합니다.

  3. serialized.[[Name]]을 valuename 속성값으로 설정합니다.

  4. serialized.[[LastModified]]를 valuelastModified 속성값으로 설정합니다.

역직렬화 단계valueserialized가 주어졌을 때 다음과 같습니다:

  1. value스냅샷 상태serialized.[[SnapshotState]]로 설정합니다.

  2. value의 기저 바이트 시퀀스를 serialized.[[ByteSequence]]로 설정합니다.

  3. valuename 속성값을 serialized.[[Name]]으로 초기화합니다.

  4. valuelastModified 속성값을 serialized.[[LastModified]]으로 초기화합니다.

4.1. 생성자

File 생성자는 선택적 딕셔너리 매개변수 사용 여부에 따라 2개 또는 3개의 매개변수로 호출할 수 있습니다. File() 생성자가 호출되면, 사용자 에이전트는 다음 단계를 실행해야 합니다:
  1. bytesfileBitsoptions를 주어 blob parts 처리의 결과로 설정합니다.

  2. n을 생성자의 fileName 인자로 설정합니다.

    참고: 기본 OS 파일 시스템은 파일명에 대해 각각 다른 규칙을 사용하므로, 생성된 파일은 UTF-16을 사용함으로써 파일명을 바이트 시퀀스로 변환할 때의 모호함을 줄일 수 있습니다.

  3. FilePropertyBag 딕셔너리 인자를 다음 하위 단계로 처리합니다:

    1. type 멤버가 제공되고 빈 문자열이 아니면, ttype 딕셔너리 멤버로 설정합니다. t에 U+0020~U+007E 범위를 벗어나는 문자가 있으면, t를 빈 문자열로 설정하고 이 하위 단계에서 반환합니다.

    2. t의 모든 문자를 ASCII 소문자로 변환합니다.

    3. lastModified 멤버가 제공되면, dlastModified 딕셔너리 멤버로 설정합니다. 제공되지 않은 경우, dUnix Epoch 이후 경과한 밀리초(즉, Date.now() [ECMA-262])로 현재 날짜와 시간으로 설정합니다.

      참고: ECMA-262의 Date 객체는 Unix Epoch 이후 경과한 밀리초 단위의 long long 값으로 변환되므로, lastModified 멤버는 Date 객체가 될 수도 있습니다 [ECMA-262].

  4. 새로운 File 객체 F를 다음과 같이 반환합니다:

    1. Fbytes 바이트 시퀀스를 참조합니다.

    2. F.sizebytes의 전체 바이트 수로 설정합니다.

    3. F.namen으로 설정합니다.

    4. F.typet로 설정합니다.

    5. F.lastModifiedd로 설정합니다.

4.1.1. 생성자 매개변수

File() 생성자는 아래 매개변수로 호출할 수 있습니다:

fileBits sequence
다음 요소들을 아무 순서로든 여러 개 받을 수 있습니다:
fileName 매개변수
USVString 타입의 파일 이름을 나타내는 매개변수입니다; 이 생성자 매개변수에 대한 규범 조건은 § 4.1 생성자에서 확인할 수 있습니다.
선택적 FilePropertyBag 딕셔너리
BlobPropertyBag멤버 외에 추가로 한 가지 멤버를 받을 수 있습니다:
  • 선택적 lastModified 멤버, long long이어야 하며; 이 멤버에 대한 규범 조건은 § 4.1 생성자에서 제공됩니다.

4.2. 속성

name, 타입 DOMString, 읽기 전용
파일의 이름. 가져올 때, 문자열로 파일 이름을 반환해야 합니다. OS 파일 시스템마다 다양한 파일명 규칙이 있으나, 여기서는 경로 정보 없이 파일 이름만을 반환합니다. 정보가 제공되지 않으면 빈 문자열을 반환해야 합니다. File 객체가 생성자를 통해 만들어진 경우, 이 속성에 대한 추가 규범 조건은 § 4.1 생성자에서 확인할 수 있습니다.
lastModified, 타입 long long, 읽기 전용
파일의 마지막 수정 날짜. 정보가 제공될 경우, long long 타입으로 Unix Epoch 이후 경과한 밀리초 단위의 마지막 수정 시간을 반환해야 합니다. 날짜와 시간을 알 수 없다면, long long 타입의 현재 날짜와 시간을 반환해야 하며, 이는 Unix Epoch 이후 경과한 밀리초 단위입니다; 즉 Date.now()와 같습니다 [ECMA-262]. File 객체가 생성자를 통해 만들어진 경우, 이 속성에 대한 추가 규범 조건은 § 4.1 생성자에서 확인할 수 있습니다.

File 인터페이스는 FileList 타입의 속성을 노출하는 객체에서 사용할 수 있으며, 이러한 객체는 HTML [HTML]에서 정의된다. File 인터페이스는 Blob을 상속하며, 불변(immutable)이고, 따라서 read operation이 시작되는 시점에 메모리로 읽을 수 있는 파일 데이터를 나타낸다. 사용자 에이전트는 읽기 시점에 더 이상 존재하지 않는 파일에 대한 읽기를 errors로 처리해야 하며, Web Worker [Workers]에서 FileReaderSync를 사용하는 경우 NotFoundError 예외를 던지거나, error 이벤트를 발행하고 error 속성이 NotFoundError를 반환하도록 해야 한다.

아래 예제에서는 파일 객체의 메타데이터를 의미 있게 표시하고, 이름과 마지막 수정 날짜가 있는 파일 객체를 생성합니다.
var file = document.getElementById("filePicker").files[0];
var date = new Date(file.lastModified);
println("You selected the file " + file.name + " which was modified on " + date.toDateString() + ".");

...

// 특정 수정 날짜로 파일 생성

var d = new Date(2013, 12, 5, 16, 23, 45, 600);
var generatedFile = new File(["Rough Draft ...."], "Draft1.txt", {type: "text/plain", lastModified: d})

...

5. FileList 인터페이스

참고: FileList 인터페이스는 "위험" 상태로 간주해야 합니다. 웹 플랫폼의 일반적인 경향은 이러한 인터페이스를 ECMAScript [ECMA-262]Array 플랫폼 객체로 대체하는 방향입니다. 특히 filelist.item(0)와 같은 문법은 위험하며, FileList의 대부분의 다른 프로그래밍적 사용은 결국 Array 타입으로의 이전에 영향을 받지 않을 것으로 보입니다.

이 인터페이스는 File 객체들의 목록입니다.

[Exposed=(Window,Worker), Serializable]
interface FileList {
  getter File? item(unsigned long index);
  readonly attribute unsigned long length;
};

FileList 객체는 직렬화 가능한 객체입니다. 직렬화 단계valueserialized가 주어졌을 때 다음과 같습니다:

  1. serialized.[[Files]]를 빈 리스트로 설정합니다.

  2. value의 각 file에 대해, file하위 직렬화serialized.[[Files]]에 추가합니다.

역직렬화 단계serialized, value가 주어졌을 때 다음과 같습니다:

  1. serialized.[[Files]]의 file에 대해, file하위 역직렬화value에 추가합니다.

예시 사용법은 일반적으로 폼 내 <input type="file"> 요소에 대한 DOM 접근 및 선택된 파일 접근을 포함합니다.
// uploadData는 form 요소입니다
// fileChooser는 'file' 타입의 input 요소입니다
var file = document.forms['uploadData']['fileChooser'].files[0];

// 대안 문법은 다음과 같을 수 있습니다
// var file = document.forms['uploadData']['fileChooser'].files.item(0);

if(file)
{
  // 파일 작업 수행
}

5.1. 속성

length, 타입 unsigned long, 읽기 전용
FileList 객체의 파일 개수를 반환해야 합니다. 파일이 없으면 이 속성은 0을 반환해야 합니다.

5.2. 메서드 및 매개변수

item(index)
index번째 File 객체를 FileList에서 반환해야 합니다. index번째 File 객체가 없으면 FileList에서 null을 반환해야 합니다.

index는 사용자 에이전트가 File 객체의 위치 값으로 처리해야 하며, 0이 첫 번째 파일을 나타냅니다. 지원되는 속성 인덱스는 0에서 File 객체 수 - 1까지의 숫자입니다. 해당 File 객체가 없다면 지원되는 속성 인덱스는 없습니다.

참고: HTMLInputElement 인터페이스는 FileList 타입의 읽기 전용 속성을 가지며, 이는 위 예시에서 접근되는 것입니다. FileList 타입의 읽기 전용 속성을 가지는 다른 인터페이스로는 DataTransfer 인터페이스가 있습니다.

6. 데이터 읽기

6.1. 파일 읽기 태스크 소스

이 명세는 파일 읽기 태스크 소스라 불리는 새로운 일반 태스크 소스를 정의하며, 이는 이 명세에서 큐잉되는 모든 태스크BlobFile 객체와 연관된 바이트 시퀀스 읽기에 사용됩니다. 이는 비동기적으로 바이너리 데이터를 읽는 기능을 트리거하는 상황에 사용됩니다.

6.2. FileReader API

[Exposed=(Window,Worker)]
interface FileReader: EventTarget {
  constructor();
  // 비동기 읽기 메서드
  undefined readAsArrayBuffer(Blob blob);
  undefined readAsBinaryString(Blob blob);
  undefined readAsText(Blob blob, optional DOMString encoding);
  undefined readAsDataURL(Blob blob);

  undefined abort();

  // 상태값
  const unsigned short EMPTY = 0;
  const unsigned short LOADING = 1;
  const unsigned short DONE = 2;

  readonly attribute unsigned short readyState;

  // File 또는 Blob 데이터
  readonly attribute (DOMString or ArrayBuffer)? result;

  readonly attribute DOMException? error;

  // 이벤트 핸들러 content attribute
  attribute EventHandler onloadstart;
  attribute EventHandler onprogress;
  attribute EventHandler onload;
  attribute EventHandler onabort;
  attribute EventHandler onerror;
  attribute EventHandler onloadend;
};

FileReader 객체는 state라는 값을 가지며, "empty", "loading", "done" 중 하나입니다. 초기값은 "empty"입니다.

FileReader 객체는 result(null, DOMString 또는 ArrayBuffer)를 가지며, 초기값은 null입니다.

FileReader 객체는 error(null 또는 DOMException) 값을 가지며, 초기값은 null입니다.

FileReader() 생성자가 호출될 때, 새로운 FileReader 객체를 반환해야 합니다.

readyState 속성의 getter는, 호출 시 thisstate에 따라 아래 단계로 분기합니다:

"empty"

EMPTY 반환

"loading"

LOADING 반환

"done"

DONE 반환

result 속성의 getter는, 호출 시 thisresult를 반환해야 합니다.

error 속성의 getter는, 호출 시 thiserror 값을 반환해야 합니다.

FileReader frread operation 알고리즘을 갖는다. 이 알고리즘은 blob, type, 그리고 선택적 encodingName이 주어지면 다음 단계를 실행한다:

  1. 만약 frstate"loading"이면, InvalidStateError DOMException을 던진다.

  2. frstate"loading"으로 설정한다.

  3. frresultnull로 설정한다.

  4. frerrornull로 설정한다.

  5. streamblob에서 get stream을 호출한 결과로 둔다.

  6. readerstream에서 getting a reader를 수행한 결과로 둔다.

  7. bytes를 비어 있는 byte sequence로 둔다.

  8. chunkPromisereaderstream에서 reading a chunk를 수행한 결과로 둔다.

  9. isFirstChunk를 true로 둔다.

  10. In parallel로, while true:

    1. chunkPromise가 이행(fulfilled)되거나 거부(rejected)될 때까지 대기한다.

    2. 만약 chunkPromise가 이행되고, isFirstChunk가 true이면, queue a task를 수행하여 fire a progress event로 명명된 loadstartfr에서 발행한다.

      우리는 loadstart를 XMLHttpRequest 동작에 맞추기 위해 동기적으로 디스패치되도록 변경할 수 있다. [Issue #119]

    3. isFirstChunk를 false로 설정한다.

    4. 만약 chunkPromisedone 속성이 false이고 value 속성이 Uint8Array 객체인 객체로 이행되었다면, 다음 단계를 실행한다:

      1. bs를 그 Uint8Array 객체가 표현하는 byte sequence로 둔다.

      2. bsbytes에 append한다.

      3. 대략 50ms가 마지막으로 이 단계들이 호출된 이후 경과했다면, queue a task를 수행하여 fire a progress event로 명명된 progressfr에서 발행한다.

      4. chunkPromisereaderstream에서 reading a chunk를 수행한 결과로 설정한다.

    5. 그렇지 않고, 만약 chunkPromisedone 속성이 true인 객체로 이행되었다면, 다음 단계를 실행하도록 queue a task하고 이 알고리즘을 중단(abort)한다:

      1. frstate"done"으로 설정한다.

      2. resultpackage data의 결과로 둔다. 인자로는 bytes, type, blobtype, 그리고 encodingName을 사용한다.

      3. 만약 package dataerror 예외를 던졌다면:

        1. frerrorerror로 설정한다.

        2. Fire a progress event로 명명된 errorfr에서 발행한다.

      4. 그 외의 경우:

        1. frresultresult로 설정한다.

        2. Fire a progress event로 명명된 loadfr에서 발행한다.

      5. 만약 frstate"loading"이 아니라면, fire a progress event로 명명된 loadendfr에서 발행한다.

        Note: load 또는 error 이벤트의 이벤트 핸들러가 다른 로드를 시작했을 수 있다. 그런 경우 이 로드에 대한 loadend 이벤트는 발행되지 않는다.

    6. 그렇지 않고, 만약 chunkPromise가 오류 error로 거부되었다면, 다음 단계를 실행하도록 queue a task하고 이 알고리즘을 중단(abort)한다:

      1. frstate"done"으로 설정한다.

      2. frerrorerror로 설정한다.

      3. Fire a progress event로 명명된 errorfr에서 발행한다.

      4. 만약 frstate"loading"이 아니라면, fire a progress event로 명명된 loadendfr에서 발행한다.

        Note: error 이벤트의 이벤트 핸들러가 다른 로드를 시작했을 수 있다. 그런 경우 이 로드에 대한 loadend 이벤트는 발행되지 않는다.

이 모든 작업에는 file reading task source를 사용한다.

6.2.1. 이벤트 핸들러 콘텐츠 속성

다음은 이벤트 핸들러 콘텐츠 속성 (및 해당 이벤트 핸들러 이벤트 타입) 으로, 사용자 에이전트가 FileReader 에서 DOM 속성으로 지원해야 하는 항목들이다:

이벤트 핸들러 콘텐츠 속성 이벤트 핸들러 이벤트 타입
onloadstart loadstart
onprogress progress
onabort abort
onerror error
onload load
onloadend loadend

6.2.2. FileReader 상태

FileReader 객체는 3가지 상태 중 하나일 수 있습니다. readyState 속성으로 객체의 상태를 확인할 수 있습니다:
EMPTY (숫자 값 0)

FileReader 객체가 생성되었으며, 대기 중인 읽기 작업이 없습니다. 읽기 메서드가 호출되지 않았습니다. 새로 생성된 FileReader 객체의 기본 상태이며, 읽기 메서드 중 하나가 호출되기 전까지 유지됩니다.

LOADING (숫자 값 1)

File 또는 Blob 이 읽히는 중입니다. 읽기 메서드 중 하나가 처리 중이며, 읽는 도중 오류가 발생하지 않았습니다.

DONE (숫자 값 2)

전체 File 또는 Blob 이 메모리로 읽혔거나, 파일 읽기 오류가 발생했거나, abort()를 사용해 읽기가 중단되었습니다. FileReader 는 더 이상 File 또는 Blob 을 읽지 않습니다. readyStateDONE으로 설정된 경우, 읽기 메서드 중 하나 이상이 이 FileReader에서 호출된 것을 의미합니다.

6.2.3. 파일 또는 Blob 읽기

FileReader 인터페이스는 여러 비동기 읽기 메서드—​readAsArrayBuffer(), readAsBinaryString(), readAsText()readAsDataURL()를 제공합니다. 이 메서드들은 파일을 메모리로 읽습니다.

참고: 동일한 FileReader 객체에서 여러 개의 읽기 메서드를 동시에 호출하면, 사용자 에이전트는 InvalidStateError를 throw합니다. readyStateLOADING일 때 추가적으로 호출되는 읽기 메서드에서 예외가 발생합니다.

(FileReaderSync 는 여러 동기 읽기 메서드를 제공합니다. FileReaderFileReaderSync의 동기 및 비동기 읽기 메서드를 통칭하여 읽기 메서드라고 부릅니다.)

6.2.3.1. readAsDataURL() 메서드

readAsDataURL(blob) 메서드는 호출 시 blob에 대해 DataURL을 사용하여 읽기 작업을 시작해야 합니다.

6.2.3.2. readAsText() 메서드

readAsText(blob, encoding) 메서드는 호출 시 blob에 대해 Textencoding을 사용하여 읽기 작업을 시작해야 합니다.

6.2.3.3. readAsArrayBuffer()

readAsArrayBuffer(blob) 메서드는 호출 시 blob에 대해 ArrayBuffer를 사용하여 읽기 작업을 시작해야 합니다.

6.2.3.4. readAsBinaryString() 메서드

readAsBinaryString(blob) 메서드는 호출 시 blob에 대해 BinaryString을 사용하여 읽기 작업을 시작해야 합니다.

참고: readAsArrayBuffer() 사용을 readAsBinaryString()보다 우선적으로 권장합니다. readAsBinaryString()는 하위 호환성을 위해 제공됩니다.

6.2.3.5. abort() 메서드

abort() 메서드가 호출되면, 사용자 에이전트는 아래 단계를 실행해야 합니다:

  1. 만약 thisstate"empty" 이거나 thisstate"done"이면, thisresultnull로 설정하고 이 알고리즘을 종료한다.

  2. 만약 thisstate"loading"이면, thisstate"done"으로 설정하고 thisresultnull로 설정한다.

  3. 연계된 task queue에서 this로부터 발생한 tasksfile reading task source에 존재한다면, 해당 task queue에서 그 tasks를 제거한다.

  4. 처리 중인 read method에 대해 알고리즘을 종료한다.

  5. progress 이벤트를 발행하되 이름을 abort로 하고, this에서 발행한다.

  6. 만약 thisstate"loading"이 아니라면, progress 이벤트를 발행하되 이름을 loadend로 하고 this에서 발행한다.

6.3. 데이터 패키징

Blob에는 패키지 데이터 알고리즘이 있으며, bytes, type, 선택적 mimeType, 선택적 encodingName이 주어졌을 때, type에 따라 아래 단계를 실행합니다:
DataURL

bytes를 DataURL [RFC2397]로 반환하며, 아래 고려사항을 따릅니다:

  • Data URL 명세 [RFC2397]에 따라 mimeType이 있으면 Data URL의 일부로 사용합니다.

  • mimeType이 없으면 미디어 타입 없이 Data URL을 반환합니다. [RFC2397].

DataURL 생성 방식을 더 명확히 지정해야 합니다. [Issue #104]

Text
  1. encoding을 실패로 설정합니다.

  2. encodingName이 있으면, encodingencoding 얻기encodingName에 대해 실행한 결과로 설정합니다.

  3. encoding이 실패이고 mimeType이 있으면:

    1. typeMIME 타입 파싱mimeType에 대해 실행한 결과로 설정합니다.

    2. type이 실패가 아니면, encodingencoding 얻기typeparameters["charset"]에 대해 실행한 결과로 설정합니다.

      blobtype 속성이 text/plain;charset=utf-8인 경우 encoding 얻기"utf-8"을 label로 실행됩니다. 사용자 에이전트는 반드시 Charset Parameter에서 인코딩의 label 부분을 파싱해 추출해야 합니다.
  4. encoding이 실패인 경우, encodingUTF-8로 설정합니다.

  5. 대체 인코딩 encoding으로 디코드bytes에 대해 실행하고 결과를 반환합니다.

ArrayBuffer

bytes를 내용으로 하는 새 ArrayBuffer를 반환합니다.

BinaryString

모든 바이트가 [0..255]의 같은 값의 코드 유닛으로 표현되는 바이너리 문자열로 bytes를 반환합니다.

6.4. 이벤트

FileReader 객체는 이 명세의 모든 이벤트에 대해 이벤트 타겟이어야 합니다.

이 명세에서 진행 이벤트를 발생시키다 e(어떤 ProgressEvent e를 특정 FileReader reader에 발생시킨다는 의미임)라고 할 때, 다음 사항이 규범적입니다:

6.4.1. 이벤트 요약

다음은 발생되는 FileReader 객체의 이벤트입니다.

이벤트 이름 인터페이스 언제 발생하는지
loadstart ProgressEvent 읽기가 시작될 때.
progress ProgressEvent blob을 읽고(및 디코딩)하는 중에
abort ProgressEvent 읽기가 중단되었을 때. 예를 들어 abort() 메서드를 호출한 경우.
error ProgressEvent 읽기에 실패했을 때(자세한 내용은 파일 읽기 오류 참고).
load ProgressEvent 읽기가 성공적으로 완료되었을 때.
loadend ProgressEvent 요청이 완료되었을 때(성공 또는 실패 모두 포함).

6.4.2. 이벤트 불변성 요약

이 섹션은 참고용입니다.

다음은 이 명세의 비동기 이벤트 발생에 대한 읽기 메서드에 적용되는 불변성입니다:

  1. loadstart 가 한 번 발행되면, 해당하는 loadend 는 읽기가 완료될 때 발행된다, 단, 다음 중 어느 하나라도 참인 경우는 예외이다:

    • read methodabort()를 사용해 취소되었고 새로운 read method가 호출된 경우

    • load 이벤트의 이벤트 핸들러 함수가 새로운 읽기를 시작한 경우

    • error 이벤트의 이벤트 핸들러 함수가 새로운 읽기를 시작한 경우.

    Note: loadstartloadend 이벤트는 일대일로 연결되어 있지 않다.

    이 예제는 "read-chaining"을 보여준다: "첫 번째" 읽기가 계속 처리되는 동안 이벤트 핸들러 내부에서 또 다른 읽기를 시작하는 방식이다.
    // 이런 종류의 코드에서...
    reader.readAsText(file);
    reader.onload = function(){reader.readAsText(alternateFile);}
    
    .....
    
    //... 첫 번째 읽기에 대해 loadend 이벤트가 발행되어서는 안 된다
    
    reader.readAsText(file);
    reader.abort();
    reader.onabort = function(){reader.readAsText(updatedFile);}
    
    //... 첫 번째 읽기에 대해 loadend 이벤트가 발행되어서는 안 된다
    
  2. progress 이벤트는 blob이 메모리에 완전히 읽혔을 때 한 번 발행된다.

  3. progress 이벤트는 loadstart 이전에는 발행되지 않는다.

  4. progress 이벤트는 abort, load, 그리고 error 중 하나가 발행된 이후에는 발행되지 않는다. abort, load, 그리고 error 중 최대 하나만 특정 읽기에 대해 발행된다.

  5. abort, load, 또는 error 이벤트는 loadend 이후에는 발행되지 않는다.

6.5. 스레드에서 읽기

웹 워커는 스레드에서의 이러한 읽기가 메인 스레드를 차단하지 않기 때문에 동기식 File 또는 Blob 읽기 API의 사용을 허용한다. 이 절은 워커 내부에서 사용할 수 있는 동기식 API를 정의한다 [Workers]. 워커는 비동기식 API(FileReader 객체) 동기식 API(FileReaderSync 객체)를 모두 사용할 수 있다.

6.5.1. FileReaderSync API

이 인터페이스는 동기적으로 읽기 위한 메서드를 제공하며, File 또는 Blob 객체를 메모리로 읽어들입니다.

[Exposed=(DedicatedWorker,SharedWorker)]
interface FileReaderSync {
  constructor();
  // 동기적으로 문자열 반환

  ArrayBuffer readAsArrayBuffer(Blob blob);
  DOMString readAsBinaryString(Blob blob);
  DOMString readAsText(Blob blob, optional DOMString encoding);
  DOMString readAsDataURL(Blob blob);
};
6.5.1.1. 생성자

FileReaderSync() 생성자가 호출될 때, 사용자 에이전트는 새로운 FileReaderSync 객체를 반환해야 합니다.

6.5.1.2. readAsText()

readAsText(blob, encoding) 메서드는 호출 시 다음 단계를 실행해야 합니다:

  1. streamblob에 대해 get stream을 실행한 결과로 설정합니다.

  2. readerstream에서 reader 얻기의 결과로 설정합니다.

  3. promisereader와 함께 stream에서 모든 바이트 읽기의 결과로 설정합니다.

  4. promise가 fulfilled 또는 rejected될 때까지 기다립니다.

  5. promise바이트 시퀀스 bytes로 fulfilled된 경우:

    1. bytes, Text, blobtype, encoding을 주어 패키지 데이터의 결과를 반환합니다.

  6. promise의 rejection reason을 throw합니다.

6.5.1.3. readAsDataURL() 메서드

readAsDataURL(blob) 메서드는 호출 시 다음 단계를 실행해야 합니다:

  1. streamblob에 대해 get stream을 실행한 결과로 설정합니다.

  2. readerstream에서 reader 얻기의 결과로 설정합니다.

  3. promisereader와 함께 stream에서 모든 바이트 읽기의 결과로 설정합니다.

  4. promise가 fulfilled 또는 rejected될 때까지 기다립니다.

  5. promise바이트 시퀀스 bytes로 fulfilled된 경우:

    1. bytes, DataURL, blobtype을 주어 패키지 데이터의 결과를 반환합니다.

  6. promise의 rejection reason을 throw합니다.

6.5.1.4. readAsArrayBuffer() 메서드

readAsArrayBuffer(blob) 메서드는 호출 시 다음 단계를 실행해야 합니다:

  1. streamblob에 대해 get stream을 실행한 결과로 설정합니다.

  2. readerstream에서 reader 얻기의 결과로 설정합니다.

  3. promisereader와 함께 stream에서 모든 바이트 읽기의 결과로 설정합니다.

  4. promise가 fulfilled 또는 rejected될 때까지 기다립니다.

  5. promise바이트 시퀀스 bytes로 fulfilled된 경우:

    1. bytes, ArrayBuffer, blobtype을 주어 패키지 데이터의 결과를 반환합니다.

  6. promise의 rejection reason을 throw합니다.

6.5.1.5. readAsBinaryString() 메서드

readAsBinaryString(blob) 메서드는 호출 시 다음 단계를 실행해야 합니다:

  1. streamblob에 대해 get stream을 실행한 결과로 설정합니다.

  2. readerstream에서 reader 얻기의 결과로 설정합니다.

  3. promisereader와 함께 stream에서 모든 바이트 읽기의 결과로 설정합니다.

  4. promise가 fulfilled 또는 rejected될 때까지 기다립니다.

  5. promise바이트 시퀀스 bytes로 fulfilled된 경우:

    1. bytes, BinaryString, blobtype을 주어 패키지 데이터의 결과를 반환합니다.

  6. promise의 rejection reason을 throw합니다.

참고: readAsArrayBuffer() 사용을 readAsBinaryString()보다 권장합니다. readAsBinaryString()는 하위 호환성을 위해 제공됩니다.

7. 오류 및 예외

파일 읽기 오류는 기본 파일 시스템에서 파일을 읽을 때 발생할 수 있습니다. 아래의 잠재적 오류 조건 목록은 참고용입니다.

7.1. 예외 발생 또는 오류 반환

이 섹션은 규범적입니다.

File 또는 Blob를 읽을 때 오류 조건이 발생할 수 있습니다.

읽기 작업File 또는 Blob를 읽는 중 오류 조건으로 종료될 수 있습니다; get stream 알고리즘이 실패하게 하는 특정 오류 조건을 실패 원인이라고 합니다. 실패 원인NotFound, UnsafeFile, TooManyReads, SnapshotState, 또는 FileLock 중 하나입니다.

동기 읽기 메서드는 아래 표의 타입에 따라 예외를 throw합니다. 해당 오류가 특정 실패 원인에 의해 발생한 경우입니다.

비동기 읽기 메서드는 error 속성을 사용하며, FileReader 객체의 이 속성은 아래 표에서 가장 적합한 타입의 DOMException 객체를 반환해야 하며, 오류가 특정 실패 원인에 의해 발생한 경우입니다. 그렇지 않으면 null을 반환해야 합니다.

타입 설명 및 실패 원인
NotFoundError File 또는 Blob 리소스를 읽을 당시 찾을 수 없으면, 이는 NotFound 실패 원인입니다.

비동기 읽기 메서드는 error 속성에서 NotFoundError 예외를 반환해야 하며, 동기 읽기 메서드는 throwNotFoundError 예외를 발생시켜야 합니다.

SecurityError 만약:
  • 특정 파일이 웹 애플리케이션에서 접근하기에 안전하지 않다고 판단된 경우, 이는 UnsafeFile 실패 원인입니다.

  • File 또는 Blob 리소스에 대해 너무 많은 읽기 호출이 발생한 경우, 이는 TooManyReads 실패 원인입니다.

비동기 읽기 메서드는 error 속성에서 SecurityError 예외를 반환할 수 있으며, 동기 읽기 메서드는 throwSecurityError 예외를 발생시킬 수 있습니다.

이 예외는 다른 실패 원인으로 설명되지 않는 상황에서 사용되는 보안 오류입니다.

NotReadableError 만약:
  • File 또는 Blob스냅샷 상태가 실제 저장소 상태와 일치하지 않으면, 이는 SnapshotState 실패 원인입니다.

  • File 또는 Blob가 읽을 수 없는 경우, 일반적으로 스냅샷 상태가 설정된 이후 권한 문제(예: 다른 애플리케이션에서 저장소의 동시 잠금)로 인해 발생하면, 이는 FileLock 실패 원인입니다.

비동기 읽기 메서드는 error 속성에서 NotReadableError 예외를 반환해야 하며, 동기 읽기 메서드는 throwNotReadableError 예외를 발생시켜야 합니다.

8. Blob 및 MediaSource 참조를 위한 URL

이 섹션에서는 BlobMediaSource 객체를 참조하기 위해 사용되는 URL 스킴에 대해 정의합니다.

8.1. 소개

이 섹션은 참고용입니다.

Blob(혹은 객체) URLblob:http://example.com/550e8400-e29b-41d4-a716-446655440000과 같은 형태의 URL입니다. 이를 통해 BlobMediaSource 를 URL로만 설계된 다른 API와 연동할 수 있습니다. 예를 들어 img 요소 등에서 사용할 수 있습니다. Blob URL은 로컬에서 생성된 데이터를 탐색하거나 다운로드를 트리거하는 데에도 사용할 수 있습니다.

이 목적을 위해 URL 인터페이스에 두 가지 정적 메서드가 노출됩니다: createObjectURL(obj)revokeObjectURL(url)입니다. 첫 번째 메서드는 URL에서 Blob로의 매핑을 생성하며, 두 번째 메서드는 해당 매핑을 해제합니다. 매핑이 존재하는 동안 Blob은 가비지 컬렉션되지 않으므로, 더 이상 필요하지 않을 경우 URL을 해제(revoke)해야 합니다. URL을 생성한 글로벌 객체가 사라질 때 모든 URL도 해제됩니다.

8.2. 모델

각 사용자 에이전트는 blob URL 저장소를 유지해야 합니다. blob URL 저장소맵(map)이며, 유효한 URL 문자열이고, blob URL 엔트리입니다.

blob URL 엔트리객체(object)(타입은 Blob 또는 MediaSource)와, environment(환경 설정 객체)로 구성됩니다.

참고: 명세들은 blob 객체 획득 알고리즘을 사용해 blob URL 엔트리객체(object)에 접근해야 합니다.

blob URL 저장소의 키(blob URL이라고도 함)는 유효한 URL 문자열로, 파싱하면 URL이 되며, scheme이 "blob"이고, host가 비어 있으며, path는 하나의 요소로, 그 요소도 유효한 URL 문자열입니다.

obtain a blob object를 수행하기 위해, blob URL entry blobUrlEntryenvironment settings object, "top-level-navigation", 또는 "top-level-self-fetch" environment가 주어졌을 때 다음 단계를 수행한다. 이 단계는 object를 반환한다.

  1. isAuthorized를 true로 둔다.

  2. 만약 environmentenvironment settings object라면, isAuthorizedblobUrlEntryenvironmentchecking for same-partition blob URL usage를 수행한 결과로 설정한다.

  3. 만약 isAuthorized가 false라면, 실패를 반환한다.

  4. blobUrlEntryobject를 반환한다.

새로운 blob URL 생성 알고리즘은 다음 단계를 실행합니다:
  1. result를 빈 문자열로 설정합니다.

  2. 문자열 "blob:"를 result에 추가합니다.

  3. settings현재 환경 설정 객체로 설정합니다.

  4. originsettingsorigin 값으로 설정합니다.

  5. serializedoriginASCII 직렬화 결과로 설정합니다.

  6. serialized가 "null"이면, 구현에 따라 정의된 값으로 설정합니다.

  7. serializedresult에 추가합니다.

  8. U+0024 SOLIDUS(/)를 result에 추가합니다.

  9. UUID [RFC4122]를 문자열로 생성하여 result에 추가합니다.

  10. result를 반환합니다.

이 알고리즘에 의해 생성될 수 있는 blob URL의 예시: blob:https://example.org/40a5fb5a-d56d-4a33-b4e2-0acf6a8e5f64.
blob URL 저장소에 엔트리 추가 알고리즘은 object가 주어졌을 때 다음 단계를 실행합니다:
  1. store를 사용자 에이전트의 blob URL 저장소로 설정합니다.

  2. url새로운 blob URL 생성의 결과로 설정합니다.

  3. entryobject현재 환경 설정 객체로 구성된 새로운 blob URL 엔트리로 설정합니다.

  4. store[url] = entry로 설정합니다.

  5. url을 반환합니다.

blob URL 저장소에서 엔트리 제거 알고리즘은 url이 주어졌을 때 다음 단계를 실행합니다:
  1. store를 사용자 에이전트의 blob URL 저장소로 설정합니다;

  2. url stringurl 직렬화의 결과로 설정합니다.

  3. store[url string] 제거를 실행합니다.

8.3. blob URL의 역참조 모델

blob URL을 해석하다 알고리즘은 URL url을 받아 다음 단계를 수행합니다:
  1. 단언: urlscheme이 "blob"이다.

  2. store를 사용자 에이전트의 blob URL 저장소로 설정한다.

  3. url stringurl 직렬화url에 대해 실행하되 fragment 제외 플래그를 설정하여 얻는다.

  4. store[url string]이 존재하면 store[url string]을 반환하고, 그렇지 않으면 실패를 반환한다.

blob URL의 파싱 및 가져오기 모델에 대한 추가 요구사항은 [URL][Fetch] 명세에 정의되어 있습니다.

8.3.1. blob URL의 오리진

이 섹션은 참고용입니다.

blob URL의 오리진은 해당 URL을 생성한 환경의 오리진과 항상 동일합니다. 단, URL이 아직 해제되지 않은 경우에 한합니다. 이는 [URL] 명세가 URL 파싱 시 blob URL 저장소에서 조회해 해당 엔트리를 사용하여 올바른 오리진을 반환하도록 구현되기 때문입니다.

만약 URL이 해제된 경우에도 오리진의 직렬화 값은 blob URL을 생성한 환경의 오리진 직렬화와 동일하게 남아 있습니다. 다만, 불투명 오리진(opaque origin)의 경우 오리진 자체는 다를 수 있습니다. 하지만 해제된 blob URL은 더 이상 해석/가져올 수 없으므로 이 차이는 관찰할 수 없습니다.

8.3.2. blob URL의 접근 제한

Blob URL은 해당 storage keyblob URL이 생성된 환경의 키와 일치하는 환경에서만 페치될 수 있다. Blob URL 탐색은 이러한 제한의 대상이 아니다.

same-partition blob URL 사용 여부 확인을 수행하기 위해, blob URL entry blobUrlEntryenvironment settings object environment가 주어졌을 때, 다음 단계를 수행한다. 이들은 boolean을 반환한다.

  1. blobStorageKeyblobUrlEntryenvironmentnon-storage 목적을 위한 storage key 획득을 수행한 결과로 둔다.

  2. environmentStorageKeyenvironmentnon-storage 목적을 위한 storage key 획득을 수행한 결과로 둔다.

  3. 만약 blobStorageKeyenvironmentStorageKeyequal하지 않다면, false를 반환한다.

  4. true를 반환한다.

8.3.3. blob URL의 생명주기

이 명세는 문서 언로드 시 정리 단계를 다음 단계로 확장합니다:

  1. environment를 해당 Document관련 설정 객체로 설정한다.

  2. store를 사용자 에이전트의 blob URL 저장소로 설정한다;

  3. store에서 environmentenvironment와 같은 모든 엔트리를 제거한다.

워커가 언로드될 때도 유사한 후크가 필요합니다.

8.4. blob URL 생성 및 해제

Blob URLURL 객체의 정적 메서드를 통해 생성 및 해제됩니다. blob URL을 해제(revoke)하면 blob URL과 그가 참조하는 리소스의 연결이 끊어지고, 해제 후 역참조 시도 시 사용자 에이전트는 네트워크 오류가 발생한 것처럼 동작해야 합니다. 이 섹션은 URL 명세 [URL]에 대한 보충 인터페이스를 설명하며, blob URL의 생성 및 해제 방법을 제시합니다.

[Exposed=(Window,DedicatedWorker,SharedWorker)]
partial interface URL {
  static DOMString createObjectURL((Blob or MediaSource) obj);
  static undefined revokeObjectURL(DOMString url);
};
createObjectURL(obj) 정적 메서드는 obj에 대해 blob URL 저장소에 엔트리 추가의 결과를 반환해야 합니다.
revokeObjectURL(url) 정적 메서드는 다음 단계를 실행해야 합니다:
  1. urlRecordurl 파싱url에 대해 실행한 결과로 설정합니다.

  2. urlRecordscheme이 "blob"이 아니면 반환합니다.

  3. entryurlRecordblob URL 엔트리로 설정합니다.

  4. entry가 null이면 반환합니다.

  5. isAuthorized동일 파티션 blob URL 사용 여부 확인entry현재 환경 설정 객체로 실행한 결과로 설정합니다.

  6. isAuthorized가 false면 반환합니다.

  7. blob URL 저장소에서 엔트리 제거url에 대해 실행합니다.

참고: 등록되지 않은 URL이나 다른 저장소 파티션에서 등록된 URL을 해제하려고 하면 오류를 발생시키지 않고 조용히 실패합니다. 이런 상황에서 사용자 에이전트가 에러 콘솔에 메시지를 표시할 수 있습니다.

참고: 해제(revoke)된 url을 역참조하면 네트워크 오류가 발생합니다. 해제 전에 시작된 요청은 성공해야 합니다.

아래 예시에서 window1window2는 서로 다른 창이지만, 동일 오리진에 있습니다; window2window1 내부의 iframe일 수도 있습니다.
myurl = window1.URL.createObjectURL(myblob);
window2.URL.revokeObjectURL(myurl);

사용자 에이전트는 하나의 글로벌 blob URL 저장소를 가지므로, 생성된 창과 다른 창에서 객체 URL을 해제할 수 있습니다. URL.revokeObjectURL() 호출은 이후 myurl을 역참조할 때 사용자 에이전트가 네트워크 오류가 발생한 것처럼 동작하도록 보장합니다.

8.4.1. blob URL 생성 및 해제 예시

Blob URL가져오기(fetch)에 사용되는 문자열이며, document에서 URL.createObjectURL()을 통해 생성된 이후 § 8.3.3 blob URL의 생명주기 참고.

이 섹션에서는 blob URL 생성 및 해제의 샘플 사용법을 설명합니다.

아래 예시에서 두 개의 img 요소 [HTML]가 동일한 blob URL을 참조합니다:
url = URL.createObjectURL(blob);
img1.src = url;
img2.src = url;
아래 예시에서는 URL.revokeObjectURL()를 명시적으로 호출합니다.
var blobURLref = URL.createObjectURL(file);
img1 = new Image();
img2 = new Image();

// 아래 두 할당 모두 정상적으로 동작함
img1.src = blobURLref;
img2.src = blobURLref;

// ... body 로드 이후
// 두 이미지가 모두 로드됐는지 확인
if(img1.complete && img2.complete) {
  // 이후 참조는 예외를 발생시켜야 함
  URL.revokeObjectURL(blobURLref);
} else {
  msg("이미지를 미리 볼 수 없습니다!");
  // 문자열 기반 참조 해제
  URL.revokeObjectURL(blobURLref);
}

위 예시에서는 하나의 blob URL에 여러 참조가 가능하며, 웹 개발자는 두 이미지 객체가 모두 로드된 후 blob URL 문자열을 해제합니다. blob URL의 사용 횟수를 제한하지 않는 것은 더 유연하지만, 누수 가능성을 높이므로, 개발자는 반드시 URL.revokeObjectURL() 호출을 짝지어 사용해야 합니다.

9. 보안 및 개인정보 보호 고려사항

이 섹션은 참고용입니다.

이 명세는 웹 콘텐츠가 기본 파일 시스템에서 파일을 읽을 수 있도록 허용하며, 파일을 고유 식별자를 통해 접근할 수 있게 하고 있기 때문에 특정 보안 고려사항의 대상이 됩니다. 이 명세는 주로 사용자가 HTML 폼의 <input type="file"/> 요소와 상호작용한다고 가정하며 [HTML], FileReader 객체로 읽는 모든 파일은 반드시 사용자가 먼저 선택했어야 합니다. 중요한 보안 고려사항에는 악의적인 파일 선택 공격(선택 루프) 방지, 시스템 민감 파일 접근 방지, 선택 이후 디스크 상의 파일 변경 방지 등이 포함됩니다.

선택 루프 방지

파일 선택 과정에서 사용자는 <input type="file"/>가 연결된 파일 선택기가 반복적으로 나타나며("반드시 선택해야 하는" 루프에서 파일 선택이 이뤄지기 전까지 닫을 수 없는 상황) 사용자 에이전트는 FileList 객체의 크기를 0으로 만들어 파일 접근을 차단할 수 있습니다.

시스템 민감 파일

(예: /usr/bin의 파일, 비밀번호 파일, 기타 운영체제 실행 파일) 보통 웹 콘텐츠에 노출되어서는 안 되며, blob URL을 통해 접근해서도 안 됩니다. 사용자 에이전트는 동기 읽기 메서드에서는 throwSecurityError 예외를 발생시키거나, 비동기 읽기의 경우 SecurityError 예외를 반환할 수 있습니다.

이 섹션은 임시이며, 이후 드래프트에서 더 많은 보안 데이터가 추가될 수 있습니다.

10. 요구사항 및 활용 사례

이 섹션에서는 이 API의 요구사항과 활용 사례를 다룹니다. 이 버전의 API가 모든 활용 사례를 만족시키는 것은 아니며, 이후 버전에서 추가적으로 다룰 수 있습니다.

감사의 글

이 명세는 SVG 워킹 그룹에서 처음 개발되었습니다. Mark Baker와 Anne van Kesteren에게 피드백에 감사드립니다.

Robin Berjon, Jonas Sicking, Vsevolod Shmyroff에게 원본 명세 편집에 감사드립니다.

Olli Pettay, Nikunj Mehta, Garrett Smith, Aaron Boodman, Michael Nordman, Jian Li, Dmitry Titov, Ian Hickson, Darin Fisher, Sam Weinig, Adrian Bateman, Julian Reschke에게 특별히 감사드립니다.

W3C WebApps WG와 public-webapps@w3.org 리스트의 참가자들에게도 감사드립니다.

준수

문서 규약

준수 요건은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. 이 문서의 규범적인 부분에서 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL”이라는 핵심 단어는 RFC 2119에서 설명된 대로 해석해야 합니다. 단, 가독성을 위해 이 단어들은 명세 내에서 모두 대문자로 표기되지 않습니다.

이 명세의 모든 텍스트는 명시적으로 비규범적인 부분, 예시, 참고로 표시된 섹션을 제외하고는 규범적입니다. [RFC2119]

이 명세의 예시는 “예를 들어”라는 단어로 시작하거나, 규범적 텍스트와 구분하여 class="example"를 사용해 다음과 같이 표시됩니다:

이것은 참고용 예시의 한 예입니다.

참고용 노트는 “참고”라는 단어로 시작하며 class="note"를 사용하여 규범적 텍스트와 구분해 다음과 같이 표시됩니다:

참고, 이것은 참고용 노트입니다.

규범적 알고리즘

알고리즘에서 명령형으로 표현된 요구사항(예: "선행 공백 문자를 제거한다" 또는 "false를 반환하고 이 단계를 중단한다")은 알고리즘을 소개하는 데 사용된 핵심 단어("must", "should", "may" 등)의 의미로 해석해야 합니다.

알고리즘이나 특정 단계로 표현된 준수 요건은 최종 결과가 동일하다면 어떤 방식으로든 구현될 수 있습니다. 특히, 이 명세에서 정의된 알고리즘은 이해하기 쉽도록 설계된 것이며, 성능을 고려한 것이 아닙니다. 구현자들은 최적화를 권장합니다.

색인

이 명세에서 정의된 용어

참조로 정의된 용어

참고문헌

규범적 참고문헌

[DOM]
Anne van Kesteren. DOM Standard. 현행 표준. URL: https://dom.spec.whatwg.org/
[ECMA-262]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[ENCODING]
Anne van Kesteren. Encoding Standard. 현행 표준. URL: https://encoding.spec.whatwg.org/
[Fetch]
Anne van Kesteren. Fetch Standard. 현행 표준. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; 외. HTML Standard. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 현행 표준. URL: https://infra.spec.whatwg.org/
[MEDIA-SOURCE-2]
Jean-Yves Avenard; Mark Watson. Media Source Extensions™. 2025년 11월 4일. WD. URL: https://www.w3.org/TR/media-source-2/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing Standard. 현행 표준. URL: https://mimesniff.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC2397]
L. Masinter. The "data" URL scheme. 1998년 8월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc2397
[RFC4122]
K. Davis; B. Peabody; P. Leach. Universally Unique IDentifiers (UUIDs). 2024년 5월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9562
[STORAGE]
Anne van Kesteren. Storage Standard. 현행 표준. URL: https://storage.spec.whatwg.org/
[STREAMS]
Adam Rice; 외. Streams Standard. 현행 표준. URL: https://streams.spec.whatwg.org/
[URL]
Anne van Kesteren. URL Standard. 현행 표준. URL: https://url.spec.whatwg.org/
[WebIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 현행 표준. URL: https://webidl.spec.whatwg.org/
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. 현행 표준. URL: https://xhr.spec.whatwg.org/

참고용 참고문헌

[Workers]
Ian Hickson. Web Workers. 2021년 1월 28일. NOTE. URL: https://www.w3.org/TR/workers/

IDL 색인

[Exposed=(Window,Worker), Serializable]
interface Blob {
  constructor(optional sequence<BlobPart> blobParts,
              optional BlobPropertyBag options = {});

  readonly attribute unsigned long long size;
  readonly attribute DOMString type;

  // slice Blob into byte-ranged chunks
  Blob slice(optional [Clamp] long long start,
            optional [Clamp] long long end,
            optional DOMString contentType);

  // read from the Blob.
  [NewObject] ReadableStream stream();
  [NewObject] Promise<USVString> text();
  [NewObject] Promise<ArrayBuffer> arrayBuffer();
  [NewObject] Promise<Uint8Array> bytes();
};

enum EndingType { "transparent", "native" };

dictionary BlobPropertyBag {
  DOMString type = "";
  EndingType endings = "transparent";
};

typedef (BufferSource or Blob or USVString) BlobPart;

[Exposed=(Window,Worker), Serializable]
interface File : Blob {
  constructor(sequence<BlobPart> fileBits,
              USVString fileName,
              optional FilePropertyBag options = {});
  readonly attribute DOMString name;
  readonly attribute long long lastModified;
};

dictionary FilePropertyBag : BlobPropertyBag {
  long long lastModified;
};

[Exposed=(Window,Worker), Serializable]
interface FileList {
  getter File? item(unsigned long index);
  readonly attribute unsigned long length;
};

[Exposed=(Window,Worker)]
interface FileReader: EventTarget {
  constructor();
  // async read methods
  undefined readAsArrayBuffer(Blob blob);
  undefined readAsBinaryString(Blob blob);
  undefined readAsText(Blob blob, optional DOMString encoding);
  undefined readAsDataURL(Blob blob);

  undefined abort();

  // states
  const unsigned short EMPTY = 0;
  const unsigned short LOADING = 1;
  const unsigned short DONE = 2;

  readonly attribute unsigned short readyState;

  // File or Blob data
  readonly attribute (DOMString or ArrayBuffer)? result;

  readonly attribute DOMException? error;

  // event handler content attributes
  attribute EventHandler onloadstart;
  attribute EventHandler onprogress;
  attribute EventHandler onload;
  attribute EventHandler onabort;
  attribute EventHandler onerror;
  attribute EventHandler onloadend;
};

[Exposed=(DedicatedWorker,SharedWorker)]
interface FileReaderSync {
  constructor();
  // Synchronously return strings

  ArrayBuffer readAsArrayBuffer(Blob blob);
  DOMString readAsBinaryString(Blob blob);
  DOMString readAsText(Blob blob, optional DOMString encoding);
  DOMString readAsDataURL(Blob blob);
};

[Exposed=(Window,DedicatedWorker,SharedWorker)]
partial interface URL {
  static DOMString createObjectURL((Blob or MediaSource) obj);
  static undefined revokeObjectURL(DOMString url);
};

이슈 색인

Blob에서 읽기가 실제로 무엇을 하는지, 발생할 수 있는 오류, 청크 크기 등 구체적으로 명시할 필요가 있습니다.
loadstart를 동기적으로 디스패치하도록 변경할 수 있습니다. XMLHttpRequest 동작에 맞추기 위해서입니다. [Issue #119]
DataURL 생성 방식의 명확한 명세가 필요합니다. [Issue #104]
워커가 언로드될 때도 유사한 후크가 필요합니다.
이 섹션은 임시이며, 이후 드래프트에서 더 많은 보안 데이터가 추가될 수 있습니다.
MDN

Blob/Blob

In all current engines.

Firefox13+Safari6+Chrome20+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12+
Node.js15.7.0+
MDN

Blob/arrayBuffer

In all current engines.

Firefox69+Safari14+Chrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js15.7.0+
MDN

Blob/size

In all current engines.

Firefox4+Safari6+Chrome5+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
Node.js15.7.0+
MDN

Blob/slice

In all current engines.

Firefox13+Safari7+Chrome21+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12+
Node.js15.7.0+
MDN

Blob/stream

In all current engines.

Firefox69+Safari14.1+Chrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js15.7.0+
MDN

Blob/text

In all current engines.

Firefox69+Safari14+Chrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js15.7.0+
MDN

Blob/type

In all current engines.

Firefox4+Safari6+Chrome5+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
Node.js15.7.0+

File/type

In all current engines.

Firefox3.6+Safari8+Chrome13+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile14+
MDN

Blob

In all current engines.

Firefox4+Safari6+Chrome5+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile11+
Node.js18.0.0+
MDN

File/File

In all current engines.

Firefox28+Safari10.1+Chrome38+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

File/lastModified

In all current engines.

Firefox15+Safari10+Chrome13+
Opera15+Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile14+
MDN

File/name

In all current engines.

Firefox3.6+Safari8+Chrome13+
Opera15+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile14+
MDN

File

In all current engines.

Firefox7+Safari4+Chrome13+
Opera11.5+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11.5+
MDN

FileList/item

In all current engines.

Firefox3+Safari4+Chrome2+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

FileList/length

In all current engines.

Firefox3+Safari4+Chrome2+
Opera11.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11.1+
MDN

FileList

In all current engines.

Firefox3+Safari4+Chrome2+
Opera11.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile11.1+
MDN

FileReader/FileReader

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile12.1+
MDN

FileReader/abort

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/abort_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/abort_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/error

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/error_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/error_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/load_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/load_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/loadend_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/loadend_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/loadstart_event

In all current engines.

Firefox79+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android79+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/loadstart_event

In all current engines.

Firefox79+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android79+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/progress_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/progress_event

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/readAsArrayBuffer

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera12+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile12+
MDN

FileReader/readAsBinaryString

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IENone
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/readAsDataURL

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/readAsText

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/readyState

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader/result

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReader

In all current engines.

Firefox3.6+Safari6+Chrome6+
Opera11+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android32+iOS Safari?Chrome for Android?Android WebView3+Samsung Internet?Opera Mobile11+
MDN

FileReaderSync/FileReaderSync

In all current engines.

Firefox8+Safari6+Chrome7+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

FileReaderSync/readAsArrayBuffer

In all current engines.

Firefox8+Safari6+Chrome9+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

FileReaderSync/readAsDataURL

In all current engines.

Firefox8+Safari6+Chrome7+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

FileReaderSync/readAsText

In all current engines.

Firefox8+Safari6+Chrome7+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

FileReaderSync

In all current engines.

Firefox8+Safari6+Chrome7+
Opera12.1+Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

URL/createObjectURL_static

In all current engines.

Firefox19+Safari6+Chrome19+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js16.7.0+
MDN

URL/revokeObjectURL_static

In all current engines.

Firefox19+Safari6+Chrome19+
Opera?Edge79+
Edge (Legacy)12+IE10+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js16.7.0+