Книга: JavaScript. Подробное руководство, 6-е издание

22.6.5. Чтение двоичных объектов

22.6.5. Чтение двоичных объектов

До сих пор двоичные объекты были для нас непрозрачными фрагментами данных, которые позволяют обращаться к их содержимому только косвенным способом, посредством URL-адресов двоичных объектов. Объект FileReader дает возможность читать символы или байты, хранящиеся в двоичном объекте, и его можно рассматривать как противоположность объекту BlobBuilder. (Для него больше подошло бы имя BlobReader, поскольку он может работать с любыми двоичными объектами, а не только с файлами.) Так как двоичные объекты могут быть очень большими и храниться в файловой системе, прикладной интерфейс чтения их содержимого действует асинхронно, во многом подобно тому, как действует объект XMLHttpRequest. Фоновым потокам доступна также синхронная версия прикладного интерфейса в виде объекта FileReaderSync, хотя они могут использовать и асинхронную версию.

Чтобы воспользоваться объектом FileReader, сначала необходимо создать его экземпляр с помощью конструктора FileReader(). Затем определить обработчики событий. Обычно в приложениях определяются обработчики событий «load» и «error» и иногда - обработчик событий «progress». Сделать это можно посредством свойств onload, onerror и onprogress или с помощью стандартного метода addEventListener(). Кроме того, объекты FileReader генерируют события «loadstart», «loadend» и «abort», которые соответствуют одноименным событиям в объекте XMLHttpRequest (раздел 18.1.4).

После создания объекта FileReader и регистрации необходимых обработчиков событий можно передать двоичный объект, содержимое которого требуется прочитать, одному из четырех методов: readAsText(), readAsArrayBuffer(), readAsDataURL() и readAsBinaryString(). (Разумеется, можно сначала вызвать один из этих методов и лишь потом зарегистрировать обработчики событий - благодаря однопоточной природе JavaScript, о которой рассказывалось в разделе 22.4, обработчики событий не могут быть вызваны, пока ваша функция не вернет управление и броузер не сможет продолжить цикл обработки событий.) Первые два метода являются наиболее важными, и только они будут описаны здесь. Каждый из этих методов чтения принимает двоичный объект Blob в первом аргументе. Метод readAsText() принимает необязательный второй аргумент, определяющий имя кодировки текста. Если кодировка не указана, метод автоматически будет обрабатывать текст в кодировках ASCII и UTF-8 (а также текст в кодировке UTF-16 с маркером порядка следования байтов (byte-order mark, BOM)).

По мере чтения содержимого указанного двоичного объекта объект FileReader будет обновлять значение своего свойства readyState. Первоначально это свойство получает значение 0, показывающее, что еще ничего не было прочитано. Когда становятся доступны какие-нибудь данные, оно принимает значение 1 и по окончании чтения - значение 2. Свойство result хранит частично или полностью прочитанные данные в виде строки или объекта ArrayBuffег. Веб-приложения обычно не опрашивают свойства readyState и result и вместо этого используют обработчик события onprogress или onload.

Пример 22.11 демонстрирует, как использовать метод readAsText() для чтения локальных текстовых файлов, выбранных пользователем.

Пример 22.11. Чтение текстовых файлов с помощью объекта FileReader

<script>
// Читает указанный текстовый файл и отображает его в элементе <рге> ниже
function readfile(f) {
  var reader = new FileReader(); // Создать объект FileReader
  reader.readAsText(f); // Прочитать файл
  reader.onload = function() { // Определить обработчик события
    var text = reader.result; 11 Это содержимое файла
    var out = document.getElementById("output"); // Найти элемент output
    out.innerHTML = // Очистить его
    out.appendChild(document.createTextNode(text));// Вывести содержимое
  } // файла
  reader.onerror = function(e) { // Если что-то пошло не так
    console.log("Error", .e); // Вывести сообщение об ошибке
  };
}
</script>
// Выберите файл для отображения:
<input type="file" files[0])"x/input>
<prex/pre>

Метод readAsArrayBuffer() похож на метод readAsText(), за исключением того, что требует приложить чуть больше усилий при работе с результатом, возвращая объект ArrayBuffег вместо строки. Пример 22.12 демонстрирует использование метода readAsArrayBuffer() для чтения первых четырех байтов из файла в виде целого числа с прямым порядком следования байтов.

Пример 22.12. Чтение первых четырех байтов из файла

<script>
// Исследует первые 4 байта в указанном двоичном объекте. Если это "сигнатура",
// определяющая тип файла, асинхронно устанавливает свойство двоичного объекта.
function typefile(file) {
  var slice = file.slice(0,4); // Читать только первые 4 байта
  var reader = new FileReader(); // Создать асинхронный FileReader
  reader.readAsArrayBuffer(slice); // Прочитать фрагмент файла
  reader.onload = function(e) {
    var buffer = reader.result; // Результат - ArrayBuffer
    var view = new DataView(buffer); // Получить доступ к результату
    var magic = view.getUint32(0, false); // 4 байта, прямой порядок
    switch(magic) { // Определить по ним тип файла
    case 0х89504Е47: file.verified_type = "image/png"; break;
    case 0x47494638: file.verified_type = "image/gif"; break;
    case 0x25504446: file.verified_type = "application/pdf"; break;
    case 0x504b0304: file.verified_type = "application/zip"; break;
    }
    console.log(file.name, file.verified_type);
  };
}
</script>
<input type="file" files[0])”></input>

В фоновых потоках выполнения вместо объекта FileReader можно использовать объект FileReaderSync. Синхронный прикладной интерфейс определяет те же методы readAsText() и readAsArrayBuffer(), которые принимают те же аргументы, что и их асинхронные версии. Разница заключается лишь в том, что синхронные методы блокируются до окончания операции и непосредственно возвращают результат в вид строки или объекта ArrayBuffer, что избавляет от необходимости использовать обработчики событий. Пример 22.14 ниже демонстрирует использование объекта FileReaderSync.

Оглавление книги


Генерация: 2.203. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз