Чтение файлов в Javascript с помощью API
Веб — браузеры, поддерживающие FileReader и <inputtype=»file»>, позволяют пользователям загружать файлы. В этой статье вы изучите API-интерфейсы File, FileReader и FileReaderSync.
Предварительные условия для начала работы
Если вы хотите следовать этой статье, вам понадобится:
- Понимание методов JavaScript, EventListener будет полезно.
- Редактор кода.
- Современный веб-браузер, поддерживающий File, FileReader и FileReaderSync.
Выбор файлов из файловой системы
Чтобы разрешить пользователям выбирать файл со своего устройства, сначала необходимо создать вход с типом файла.
<inputtype=»file» id=»inputElement» />
Чтобы фактически получить файлы из этого ввода, вам нужно будет получить доступ к свойству files элемента input. Лучше всего это сделать, зарегистрировав прослушиватель событий изменений на входном элементе. Таким образом, функция обратного вызова будет вызываться каждый раз, когда пользователь выбирает файл.
То, как вы это сделаете, будет зависеть от используемой вами структуры. Чтобы сделать это руководство как можно более широко применимым, мы будем использовать vanillaJS.
Полученный selectedFile является объектом File.
Свойства файлов
Ввод файла дает нам объекты файла, поэтому в дополнение к содержимому самого файла у нас есть доступ к некоторой дополнительной информации, такой как:
- name — имя файла, включая расширение, но без пути (например, «cat_photo.png»)
- size — размер файла в байтах. Чтобы получить размер в более удобочитаемом формате, вы можете использовать библиотеку, такую как размер файла или байты. Для простых случаев использования вы даже можете написать свою собственную логику преобразования.
- type — тип MIME файла (например, «текст/обычный», «изображение/png»)
- LastModified — дата последнего изменения файла, представленная в виде количества миллисекунд, прошедших с эпохи Unix (1 января 1970 года в полночь). Вы можете использовать конструктор даты для преобразования этой метки времени в более полезный объект даты javascript.
Файлы также имеют два других свойства: File.LastModifiedDate и File.webkitRelativePath, первый изкоторых является устаревшим, а второй нестандартным, поэтому вам, вероятно, следует избегать их использования. Имейте в виду,что все эти свойства доступны только для чтения.
Файлы и большие двоичные объекты
В дополнение к файлу, javascript имеет еще один способ представления файлов, называемый Blob
Blob-объект содержит данные общего файла, а также информацию о его размере и типе. Файл на самом деле-это просто более специализированный большой двоичный объект, используемый для представления конкретных файлов в файловой системе пользователя. Он наследует все методы и свойства Blob-объекта и содержит некоторую дополнительную информацию об имени файла и дате последнего изменения.
Эти два в основном взаимозаменяемы, и вы можете использовать один почти везде, где вы можете использовать другой. Однако, если вам абсолютно необходимо преобразовать их, вы можете сделать это с помощью конструктора другого типа.
Чтение содержимого файлов
Итак, мы знаем, как выбирать и получать информацию о файлах, но как мы на самом деле читаем то, что находится внутри них? Ну, это зависит от того, что это за файл и что вы хотите с ним сделать. Для целей этой статьи мы сосредоточимся только на изображениях и текстовых файлах.
Наиболее гибким и хорошо поддерживаемым методом чтения содержимого файла является API FileReader. Это API, управляемый событиями, поэтому вместо того, чтобы просто вызывать функцию и получать содержимое файла, мы должны предпринять некоторые дополнительные шаги.
Давайте начнем с чтения текстового файла:
- Сначала мы получаем элемент ввода файла и регистрируем на нем прослушиватель событий изменений, назначая функцию обратного вызова его свойству onchange.
- Мы получаем выбранный файл
- Мы проверяем, действительно ли файл был выбран, и если нет (что может произойти, например, если пользователь нажмет «отмена» в окне выбора), мы выходим из функции
- Затем мы создадим экземпляр FileReader
- Затем мы регистрируем любые обработчики событий, которые нам могут понадобиться. Для доступа к содержимому файла нам действительно нужно только событие загрузки, которое срабатывает, когда операция чтения успешно завершена. Однако, как правило, неплохо также зарегистрировать обработчик ошибок. Полный список возможных событий доступен чуть дальше в статье, а также некоторые советы по обработке ошибок, поэтому продолжайте читать.
- После регистрации всех прослушивателей событий мы инициируем операцию чтения, вызывая один из методов readAs, в данном случае readAsText.
- После завершения операции чтения содержимое файла будет доступно в свойстве reader.result, доступ к которому мы можем получить внутри обработчика событий загрузки (функция обратного вызова reader.onload).
Быстрый совет: Вы можете получить доступ к считывателю внутри обработчика событий несколькими способами: reader === e.target === this. Имейте в виду, что это недоступно в функциях со стрелками.
Обработка ошибок
В случае ошибки вызывается обработчик событий ошибки, и вы можете найти объект ошибки в reader.error.
Возможные коды ошибок:
- FileError.NOT_FOUND_ERR — файл не найден
- FileError.NOT_READABLE_ERR — файл не может быть прочитан
- Ошибка файла.SECURITY_ERR — возникла проблема с безопасностью
- Ошибка файла.ABORT_ERR — выбрасывается при вызове reader.abort (), когда операция чтения не выполняется
В большинстве случаев нет необходимости различать эти типы ошибок, возможно, за исключением ABORT_ERR, который, как правило, безвреден и может быть проигнорирован.
Состояние готовности
Операция чтения асинхронна, поэтому не пытайтесь получить доступ к reader.result сразу после вызова readAs. Если вам действительно нужно проверить значение reader.result вне обработчика событий загрузки, сначала проверьте значение reader.readyState, которое будет одним из 3 значений:
- Считыватель был создан, но метод readAs еще не был вызван. (ПУСТО)
- Был вызван один из методов readAs. Выполняется операция чтения, и пока никаких ошибок не произошло. (ЗАГРУЗКА)
- Операция завершена. Это может означать одно из трех: файл был успешно прочитан, произошла ошибка чтения или была вызвана функция reader.abort (), и операция была отменена. (СДЕЛАНО)
Свойство reader.result будет заполнено только в случае успешной операции чтения. Во всех остальных случаях он будет равен нулю.
То же самое относится и к reader.error, доступ к которому должен осуществляться внутри обработчика событий ошибок.
Типы событий FileReader
Мы уже рассмотрели два наиболее распространенных типа событий чтения, теперь давайте быстро рассмотрим остальные. FileReader имеет шесть типов событий:
- load — срабатывает при успешном завершении операции чтения
- error — срабатывает, когда операция чтения сталкивается с ошибкой
- progress — периодически срабатывает во время чтения файла или большого двоичного объекта и содержит информацию о ходе выполнения операции. Может использоваться для реализации загрузочных стержней.
- abort- срабатывает при отмене операции чтения, т. е. когда reader.abort() вызывается
- loadstart — срабатывает при запуске операции чтения
- loadend — срабатывает при завершении операции чтения, независимо от того, была ли она успешной или неудачной
Вы, вероятно, заметили, что события FileReader работают аналогично обычным событиям DOM. Я нахожу, что, думая о них как о таковых, намного легче понять их нелинейную, асинхронную природу.
Примечание: Как и в случае с событиями DOM, можно зарегистрировать обработчики событий с помощью addEventListener или назначив функцию обратного вызова свойству «oneventname» считывателя.
Blob.text()
Также стоит отметить, что для чтения текстовых файлов существует более новый и простой метод — Blob.text(). Помните, что файл-это просто большой двоичный объект с некоторыми дополнительными функциями, поэтому он наследует все методы большого двоичного объекта, включая этот. Это означает, что вы можете использовать этот метод как для больших двоичных объектов, так и для файлов.
Вывод
В этой статье вы изучили API-интерфейсы File, FileReader и FileReaderSync. Потратьте время, чтобы проверить поддержку браузером этих функций, чтобы убедиться, что они применимы к пользователям ваших проектов.