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

Событие прогресса (Progress events)

События показывающее прогресс какого-либо процесса очень распространены. Эти события спроектированы для отображения прогресса передачи данных. Такая передача происходит как при запросе данных с сервера, так и при запросе данных с диска, что FileReader и делает.

Есть шесть событий прогресса:

  • loadstart – указывает что процесс загрузки данных начался. Это событие всегда срабатывает первым
  • progress – срабатывает несколько раз по мере загрузки данных, дает доступ к промежуточным данным
  • error –  срабатывает когда загрузка окончилась неудачей
  • abort – срабатывает когда загрузка данных была отменена вызовом метода abort() (такой метод есть и у XMLHttpRequest).
  • load – срабатывает только тогда, когда все данные были успешно загружены
  • loadend – срабатывает, когда объект завершил передачу данных. Всегда срабатывает после error, abort или load.

Два события, error и load, были обсуждены в моем предыдущем посте. Другие события дают более узкий контроль над процессом передачи данных.

Отслеживание прогресса

Когда вы хотите отследить прогресс чтения файлов, используйте событие progress. Объект event который является параметром этого события содержит 3 поля, для контроля передаваемых данных 

  • lengthComputable – тип boolean указывает может ли браузер определить размер файла
  • loaded – число байтов которые уже загружены
  • total – общее количество байтов которые нужно прочитать

Эти данные позволяют создать прогресс бар, который будет показывать информацию от прогрессе загрузки . Например, вы можете использовать элемент HTML5 <progress> для мониторинга прогресса чтения файла. Вы можете связать уровень прогресса с фактическими данными, используя следующий код:

var reader = new FileReader(),
progressNode = document.getElementById("my-progress");

reader.onprogress = function(event) {
	if (event.lengthComputable) {
		progressNode.max = event.total;
		progressNode.value = event.loaded;
	}
};

reader.onloadend = function(event) {
	var contents = event.target.result,
	error = event.target.error;
	if (error != null) {
		console.error("File could not be read! Code " + error.code);
	} else {
		progressNode.max = 1;
		progressNode.value = 1;
		console.log("Contents: " + contents);
	}
};

reader.readAsText(file);

Это похоже на подход, который использует Gmail при реализации "drag and drop" загрузки файла, где вы видите прогрессбар сразу после добавления файла к электронному письму. Этот прогрессбар показывает, насколько файл уже передан на сервер.

Работа с ошибками

Даже если Вы читате локальный файл, это может привести к краху чтения. Спецификация File API определяет 4 типа ошибок: 

  • NotFoundError – файл не может быть найден.
  • SecurityError – чтение файла не безопасно либо запрещено. Если файл слишком большой то Вы тоже увидите эту ошибку.
  • NotReadableError – файл существует, но не может быть прочитан, скорее всего, из-за проблемы с правами доступа.
  • EncodingError – возникает к примеру когда читаете файл как dataURI и длинна его выходит за пределы поддерживаемые браузером

При возникновении ошибки во время чтения файла, полю объекта FileReader error присваивается экземпляр одной из вышеупомянутых ошибок. По крайней мере, именно так написано в спецификации. На самом деле, браузеры реализовывают это как объект FileError, который имеет поле код, указывающий тип ошибки, которая произошла. Каждый тип ошибки представляет собой целочисленную константу:

 

  • FileError.NOT_FOUND_ERR для ошибки NotFoundError.
  • FileError.SECURITY_ERR для SecurityError.
  • FileError.NOT_READABLE_ERR для NotReadableError.
  • FileError.ENCODING_ERR для EncodingError.
  • FileError.ABORT_ERR когда вызван abort() в процессе чтения файла.

 

Вы можете проверить тип ошибки либо во время события error или во время события loadend:

var reader = new FileReader();

reader.onloadend = function(event) {
	var contents = event.target.result,
		error = event.target.error;
	if (error != null) {
		switch (error.code) {
			case error.ENCODING_ERR:
				console.error("Проблемы кодировки!");
				break;

			case error.NOT_FOUND_ERR:
				console.error("Файл не найден!");
				break;

			case error.NOT_READABLE_ERR:
				console.error("Файл не может быть прочитан!");
				break;

			case error.SECURITY_ERR:
				console.error("Проблема безопасности в файл!");
				break;

			default:
				console.error("Я понятия не имею, что случилось!");
		}
	} else {
		progressNode.max = 1;
		progressNode.value = 1;
		console.log("Contents: " + contents);
	}
};

reader.readAsText(file);

Что дальше

Объект FileReader это полнофункциональный объект с большим количеством методов сходных с методами XMLHttpRequest. из прошлых постов, Вы должны уметь считывать данные из файла с помощью JavaScript и отправлять данные на сервер, если это необходимо. Тем не менее, экосистема File API гораздо больше, чем описано  в этой серии статей, и в следующей части вы узнаете о новых мощных функциях, предназначенных для работы с файлами.

Чтение файлов на JavaScript вообще штука интересная, Вы можете сохранить данные на карту памяти SD/SDHC/Secure Digital любых объемов? а затем прочитать их при помощи этого же FileAPI, что несомненно очень удобно. С учетом того, что онлайн приложения развиваются семимильными шагами покупаем карту SD SDHC  в каком нибудь SotMarket и экспериментируем с чтением файла через JavaScript FileAPI уже сейчас.  

Ссылки по теме

Progress Events
File API

Связанные статьи

Работа с файлами в JavaScript, Часть 1: Основы
Работа с файлами в JavaScript, Часть 2: FileReader
Работа с файлами в JavaScript, Часть 4:Объект URL

Оставлять комментарии могут только зарегистрированные пользователи

Комментарии  

pasha
# pasha 14.11.2012 09:24
Спасибо ;) Познавательная статья.