File API | Чтение данных

File API | Чтение данных

6.1. Источник задачи чтения файла

Эта спецификация определяет новый общий источник задачи, называемый источником задачи чтения файла (file reading task source), который используется для всех задач, поставленных в очередь в этой спецификации, для чтения последовательностей байтов, связанных с объектами Blob и File. Он должен использоваться для функций, которые запускаются в ответ на асинхронное чтение двоичных данных.

 

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 или ArrayBuffer)? result;
 readonly attribute DOMException? error;

 // атрибуты содержимого обработчика событий
 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 при вызове переключает состояние объекта контекста (этого this) и выполняет связанный шаг:

«empty»
Вернуть EMPTY

«loading»
Вернуть LOADING

«done»
Вернуть DONE

Получатель атрибута result при вызове должен возвращать результат объекта контекста (этого this).

 

Получатель атрибута error при вызове должен возвращать ошибку объекта контекста (этого this).

FileReaderfr имеет связанный алгоритм операции чтения (read operation), который при заданном blob, type и необязательном encodingName выполняет следующие шаги:

1. Если состояние fr является "loading", выбросить исключение InvalidStateError DOMException.
2. Установите для fr состояние "loading".
3. Установите для результата fr значение null.
4. Установите для ошибки fr значение null.
5. Пусть поток stream будет результатом вызова получения потока (get stream) для blob.
6. Пусть читатель reader будет результатом получения читателя из потока stream.
7. Пусть байты bytes будут пустой последовательностью байтов.
8. Пусть кусочек Обещания chunkPromise будет результатом чтения фрагмента из потока stream с помощью читателя reader.
9. Пусть isFirstChunk будет истинным - true.
10. Параллельно, пока истина - true:
  1. Подождите, пока chunkPromise будет выполнен или отклонён.
  2. Если chunkPromise является выполненным, а isFirstChunk имеет значение true, поставить задачу в очередь для запуска события выполнения, называемого "loadstart", на fr.
Проблема 2

Мы могли бы изменить loadstart, чтобы он отправлялся синхронно, чтобы соответствовать поведению XMLHttpRequest. <https://github.com/w3c/FileAPI/issues/119>

  3. Установите для isFirstChunk значение false.
  4. Если chunkPromise является выполненным с помощью объекта, свойство "done" которого имеет значение false, а свойство "value" - объект "Uint8Array", выполните следующие действия:
    1. Пусть bs будет байтовой последовательностью (byte sequence), представленной объектом Uint8Array.
    2. Добавить bs к байтам bytes.
    3. Если с момента последнего вызова этих шагов прошло примерно 50ms, поставьте задачу в очередь для запуска события прогресса, которое называется "progress" в fr.
    4. Установите chunkPromise равным результату чтения фрагмента из потока stream с помощью средства чтения reader.
  5. В противном случае, если chunkPromise является выполненным с объектом, свойство "done" которого истинно, поставьте задачу в очередь для выполнения следующих шагов и прервите этот алгоритм:
    1. Установите для fr состояние "done" (готово).
    2. Пусть result будет результатом данных пакета с заданными байтами bytes, типом type, "type" blob и encodingName.
    3. Если данные пакета вызвали ошибку исключения error:
      1. Установите для ошибки fr значение error.
      2. Запустить событие прогресса под названием "error" на fr.
    4. Иначе:
      1. Установите результат fr равным result.
      2. Запустить событие выполнения под названием "load" на fr.
    5. Если состояние fr не "loading", вызовите событие прогресса, называемое "loadend", на fr.
Примечание

Обработчик событий для событий «load» или «error» (загрузки или ошибок) мог запустить другую загрузку, если это произойдет, событие «loadend» для этой загрузки не запускается.

  6. В противном случае, если chunkPromise отклоняется с ошибкой error, поставьте задачу в очередь для выполнения следующих шагов и прервите этот алгоритм:
    1. Установите для состояния fr - "done".
    2. Установите для ошибки fr значение error.
    3. Запустить событие прогресса под названием "error" на fr.
    4. Если состояние fr не "loading", вызовите событие прогресса с именем "loadend" на fr.
Примечание

Обработчик события «error» мог запустить другую загрузку, в этом случае событие «loadend» для этой загрузки не запускается.

 

Используйте источник задачи чтения файла для всех этих задач.

 

 

6.2.1. Атрибуты содержимого Обработчика Событий

Ниже приведены атрибуты содержимого обработчика событий (и соответствующие им типы событий обработчика событий), которые пользовательские агенты должны поддерживать в FileReader как атрибуты DOM:

 

6.2.2. Состояния чтения файлов

Объект FileReader может находиться в одном из трех состояний. Атрибут readyState сообщает вам, в каком состоянии находится объект:

EMPTY (числовое значение 0)

Объект FileReader создан, и ожидающих чтений нет. Ни один из методов чтения не был вызван. Это состояние по умолчанию для вновь созданного объекта FileReader до тех пор, пока для него не будет вызван один из методов чтения.

LOADING (числовое значение 1)

Читается объект File или Blob. Один из методов чтения обрабатывается, и во время чтения ошибок не произошло.

DONE (числовое значение 2)

Весь File или Blob был прочитан в память, ИЛИ произошла ошибка чтения файла, ИЛИ чтение было прервано с помощью abort(). FileReader больше не читает File или Blob. Если для параметра readyState установлено значение DONE, это означает, что в этом FileReader был вызван по крайней мере один из методов чтения.

 

6.2.3. Чтение файла File или большого двоичного объекта Blob

Интерфейс FileReader предоставляет несколько методов асинхронного чтения (asynchronous read methods) — readAsArrayBuffer(), readAsBinaryString(), readAsText() и readAsDataURL(), которые считывают файлы в память.

Примечание

Если для одного и того же объекта FileReader вызывается несколько одновременных методов чтения, пользовательские агенты генерируют ошибку InvalidStateError для любого из методов чтения, возникающих, когда «readyState = LOADING«.

(FileReaderSync предоставляет несколько методов синхронного чтения. В совокупности методы синхронного и асинхронного чтения FileReader и FileReaderSync называются просто методами чтения (read methods).)

 

6.2.3.1. Метод readAsDataURL()

Метод readAsDataURL( blob ) при вызове должен инициировать операцию чтения для большого двоичного объекта blob с DataURL.

 

6.2.3.2. Метод readAsText()

Метод readAsText( blob, encoding ) при вызове должен инициировать операцию чтения для большого двоичного объекта blob с текстом Text и кодировкой encoding.

 

6.2.3.3. Метод readAsArrayBuffer()

Метод readAsArrayBuffer( blob ) при вызове должен инициировать операцию чтения для большого двоичного объекта blob с помощью ArrayBuffer.

 

6.2.3.4. Метод readAsBinaryString()

Метод readAsBinaryString( blob ) при вызове должен инициировать операцию чтения для большого двоичного объекта blob с помощью BinaryString.

Примечание

Использование readAsArrayBuffer() предпочтительнее readAsBinaryString(), которое предусмотрено для обратной совместимости.

 

6.2.3.5. Метод abort()

Когда вызывается метод abort(), пользовательский агент должен выполнить следующие шаги:

1. Если состояние объекта контекста (this) является "empty" или если состояние объекта контекста (this) является "done", установите результат объекта контекста (this) равным null и завершите этот алгоритм.
2. Если состояние объекта контекста (this) является "loading", установите состояние объекта контекста (this) на "done" и установите для результата объекта контекста (this) значение null.
3. Если есть какие-либо задачи из объекта контекста (this) в источнике задач чтения файла в связанной очереди задач, удалите эти задачи из этой очереди задач.
4. Завершить алгоритм обрабатываемого метода чтения.
5. Запустить событие выполнения, называемое прерыванием "abort", в объекте контекста (this).
6. Если состояние объекта контекста (this) не является "loading", запускайте событие выполнения, называемое "loadend", в объекте контекста (this).

 

6.3. Данные об упаковке

Blob имеет связанный алгоритм упаковки данных (package data), заданные байты bytes, тип type, необязательный mimeType и необязательный encodingName, который включает тип type и выполняет связанные шаги:

 

DataURL

Вернуть байты bytes как DataURL [RFC2397 #] с учетом следующих соображений:

  • Используйте mimeType как часть URL-адреса Данных, если он доступен в соответствии со спецификацией URL-адреса Данных [RFC2397].
  • Если mimeType недоступен, верните URL-адрес Данных без медиа-типа. [RFC2397].
Проблема 3

(Лучше указать, как генерируется DataURL. <https://github.com/w3c/FileAPI/issues/104>)

 

Text

1. Пусть кодирование encoding будет неудачным.
2. Если encodingName присутствует, установите кодировку encoding на результат получения кодировки из encodingName.
3. Если кодировка encoding не удалась и присутствует mimeType:
  1. Пусть type будет результатом синтаксического анализа MIME-типа, заданного mimeType.
  2. Если type не является ошибкой, установите кодировку encoding на результат получения кодировки из параметров type["charset"].
Пример № 6

Если у blob есть атрибут типа «type» — text/plain;charset=utf-8, то получение кодировки выполняется с использованием «utf-8» в качестве метки. Обратите внимание, что пользовательские агенты должны анализировать и извлекать часть параметра Charset, которая составляет метку label кодировки.

4. Если кодировка encoding не удалась, установите кодировку encoding в UTF-8.
5. Расшифруйте байты bytes с использованием резервной кодировки encoding и верните результат.

 

ArrayBuffer

Верните новый ArrayBuffer, содержимое которого — байты bytes.

 

BinaryString

Верните байты bytes как двоичную строку, в которой каждый байт представлен единицей кода равного значения [0..255].

 

6.4. События

Объект FileReader должен быть целью для всех событий в этой спецификации.

Когда в этой спецификации говорится, что нужно запускать событие выполнения с именем « (для некоторого ProgressEvent « у данного средства чтения FileReader в качестве объекта контекста), следующее является нормативным:

  • Событие прогресса «e» не всплывает. «e.bubbles» должно иметь значение false [DOM]
  • Событие прогресса «e» НЕ отменяется. «e.cancelable» должен иметь значение false [DOM]

 

6.4.1. Резюме события

Следующие события запускаются в объектах FileReader.

Название события Интерфейс Сработало, когда…
loadstart ProgressEvent Когда начнется чтение.
progress ProgressEvent При чтении (и декодировании) blob
abort ProgressEvent Когда чтение было прервано. Например, вызвав метод abort().
error ProgressEvent Когда чтение не удалось (см. Ошибки чтения файла).
load ProgressEvent Когда чтение успешно завершено.
loadend ProgressEvent Когда запрос выполнен (успешно или неудачно).

 

6.4.2. Сводка инвариантов событий

Этот раздел носит информативный характер.

Ниже приведены инварианты, применимые к запуску события для данного асинхронного метода чтения в этой спецификации:

1. После запуска loadstart соответствующая нагрузка срабатывает по loadend, ЕСЛИ не выполняется одно из следующих условий:
- метод чтения был отменен с помощью abort(), и был вызван новый метод чтения
- функция обработчика событий для события загрузки load инициирует новое чтение
- функция обработчика события ошибки error инициирует новое чтение.
Примечание

События loadstart и loadend не связаны однозначно.

Пример № 7

В этом примере демонстрируется «цепочка чтения»: инициирование другого чтения из обработчика событий, в то время как «первое» чтение продолжает обработку.

// В коде вроде ...
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). Для данного чтения не более одного срабатывания прерывания, загрузки и ошибки. (Самое большее один из прерываний, загрузок и ошибок срабатывает для данного чтения.)
5. После окончания загрузки loadend не возникает никаких событий прерывания (abort), загрузки (load) или ошибки (error).

6.5. Чтение в Потоках

Веб-Воркеры позволяют использовать синхронные API чтения File или Blob (файлов или больших двоичных объектов), поскольку такие чтения в потоках не блокируют основной поток. В этом разделе определяется синхронный API, который можно использовать в Workers [[Web Workers]]. Рабочие могут использовать как асинхронный API (объект FileReader), так и синхронный API (объект FileReaderSync).

 

6.5.1. Интерфейс FileReaderSync

Этот интерфейс предоставляет методы для синхронного чтения (synchronously read) объектов 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. Пусть поток stream будет результатом вызова получения потока для blob.
2. Пусть читатель reader будет результатом получения читателя из потока stream.
3. Пусть обещание promise будет результатом чтения всех байтов из потока stream с помощью reader.
4. Подождите, пока обещание promise будет выполнено (fulfilled) или отклонено (rejected).
5. Если обещание promise выполнено (fulfilled) с байтовой последовательностью bytes:
  1. Возвращает результат данных пакета с указанием байтов bytes, текста Text, типа "type"  blob и encoding.
6. Укажите причину отклонения обещания promise.

 

6.5.1.3. Метод readAsDataURL()

Метод readAsDataURL( blob ) при вызове должен выполнить следующие шаги:

1. Пусть поток stream будет результатом вызова получения потока для blob.
2. Пусть читатель reader будет результатом получения читателя из потока stream.
3. Пусть обещание promise будет результатом чтения всех байтов из потока stream с помощью reader.
4. Подождите, пока обещание promise будет выполнено (fulfilled) или отклонено (rejected).
5. Если обещание promise выполнено (fulfilled) с байтовой последовательностью bytes:
  1. Возвращает результат данных пакета с указанием байтов bytes, DataURL и типа "type" blob.
6. Укажите причину отклонения обещания promise.

 

6.5.1.4. Метод readAsArrayBuffer()

Метод readAsArrayBuffer( blob ) при вызове должен выполнить следующие шаги:

1. Пусть поток stream будет результатом вызова получения потока для blob.
2. Пусть читатель reader будет результатом получения читателя из потока stream.
3. Пусть обещание promise будет результатом чтения всех байтов из потока stream с помощью reader.
4. Подождите, пока обещание promise будет выполнено (fulfilled) или отклонено (rejected).
5. Если обещание promise выполнено (fulfilled) с байтовой последовательностью bytes:
  1. Возвращает результат данных пакета с указанием байтов bytes, ArrayBuffer и типа "type" blob.
6. Укажите причину отклонения обещания promise.

 

6.5.1.5. Метод readAsBinaryString()

Метод readAsBinaryString( blob ) при вызове должен выполнить следующие шаги:

1. Пусть поток stream будет результатом вызова получения потока для blob.
2. Пусть читатель reader будет результатом получения читателя из потока stream.
3. Пусть обещание promise будет результатом чтения всех байтов из потока stream с помощью reader.
4. Подождите, пока обещание promise будет выполнено (fulfilled) или отклонено (rejected).
5. Если обещание promise выполнено (fulfilled) с байтовой последовательностью bytes:
  1. Вернуть результат данных пакета с указанием байтов bytes, BinaryString и типа "type" blob.
6. Укажите причину отклонения обещания promise.
Примечание

Использование readAsArrayBuffer() предпочтительнее readAsBinaryString(), которое предусмотрено для обратной совместимости.

 

 

Информационные ссылки

Стандарт File API — Раздел «Чтение данных» — https://www.w3.org/TR/FileAPI/#reading-data-section