# File та FileReader Об’єкт [File](https://www.w3.org/TR/FileAPI/#dfn-file) наслідується від `Blob` та надає додаткові можливості для роботи з файловою системою. Є два способи створити екземпляр `File`. По-перше, можна скористатися конструктором схожим на `Blob`: ```js new File(fileParts, fileName, [options]) ``` - **`fileParts`** -- масив значень, що можуть мати тип Blob/BufferSource/String. - **`fileName`** -- рядок з іменем файлу. - **`options`** -- необов’язковий об’єкт з властивостями: - **`lastModified`** -- мітка часу (ціле число) останньої зміни. По-друге, частіше ми отримуємо файл із ``, перетягуванням чи іншим способом. У такому випадку інформацію про файл заповнює ОС. Оскільки клас `File` наслідує `Blob`, екземпляри `File` мають такі самі властивості і ще додаткові: - `name` -- ім’я файлу, - `lastModified` -- мітка часу останньої зміни. Щоб отримати об’єкт `File` з `` потрібно: ```html run ``` ```smart Компонент введення (input) дозволяє обрати декілька файлів разом, які будуть доступні в об'єкті `input.files`. Оскільки тут ми завантажуємо один файл, то можемо скористатися `input.files[0]`. ``` ## FileReader [FileReader](https://www.w3.org/TR/FileAPI/#dfn-filereader) -- об’єкт для зчитування даних з `Blob`, а отже і з `File` також. Дані передаються за допомогою подій, оскільки зчитування даних з диску потребує часу. Конструктор: ```js let reader = new FileReader(); // без аргументів ``` Основні методи: - **`readAsArrayBuffer(blob)`** -- прочитати дані в бінарному форматі і зберегти в `ArrayBuffer`. - **`readAsText(blob, [encoding])`** -- прочитати дані як текст із заданим кодуванням (типово `utf-8`). - **`readAsDataURL(blob)`** -- прочитати бінарні дані та закодувати у форматі base64 data url. - **`abort()`** -- відмінити операцію. Вибір `read*` методу залежить від формату даних з яким ми хочемо працювати. - `readAsArrayBuffer` -- використовується для низькорівневих операцій з бінарними даними. Для високорівневих операцій, як отримання зрізів, об’єкт `File` успадковується від `Blob`, тому його можна використовувати безпосередньо без читання файлу. - `readAsText` -- використовується для текстових файлів, вміст буде записано в рядок. - `readAsDataURL` -- використовується, якщо ми хочемо використати дані як вміст `src` тегу `img` або інших. Можна скористатися іншим способом для цього, що описано в розділі : `URL.createObjectURL(file)`. Протягом зчитування файлу можуть виникнути події: - `loadstart` -- зчитування файлу почалось. - `progress` -- періодично виникає протягом зчитування. - `load` -- зчитування завершилось без помилок. - `abort` -- викликано метод `abort()`. - `error` -- протягом зчитування виникла помилка. - `loadend` -- зчитування закінчилось успішно чи з помилкою. Після закінчення зчитування файлу результат можна отримати за допомогою: - `reader.result` якщо зчитування закінчилося успішно, без помилки - `reader.error` якщо протягом зчитування виникла помилка. Найпотрібніші події при зчитуванні файлу: `load` та `error`. Приклад зчитування файлу: ```html run ``` ```smart header="`FileReader` для Blob" Як описано в розділі , `FileReader` може зчитати вміст будь-яких бінарних об’єктів, а не тільки файлів. Це можна використати для перетворення бінарних Blob об’єктів у інші формати: - `readAsArrayBuffer(blob)` -- в `ArrayBuffer`, - `readAsText(blob, [encoding])` -- в рядок (альтернативний спосіб до `TextDecoder`), - `readAsDataURL(blob)` -- в формат base64-кодованого url. ``` ```smart header="`FileReaderSync` доступний всередині Web Workers" Для Web Workers існує [FileReaderSync](https://www.w3.org/TR/FileAPI/#FileReaderSync) -- синхронний варіант `FileReader`. Його метод `read*` не створює подій, а просто повертає результат, як звичайна функція. Синхронний метод бажано використовувати тільки всередині Web Worker, бо затримки під час синхронного виклику, що ймовірні при синхронному читанні з файлів, в Web Worker є менш важливими. Вони не впливають на сторінку. ``` ## Підсумки `File` успадковується від `Blob`. На додачу до методів та властивостей, що доступні в `Blob`, об’єкт `File` має властивості `name`, `lastModified` та ще можливість читати файли з файлової системи. Переважно об’єкт `File` отримується з користувацького вводу, як `` чи Drag'n'Drop подіями (`ondragend`). `FileReader` об’єкт може прочитати з файлу чи blob в одному з трьох форматів: - Рядок (`readAsText`). - `ArrayBuffer` (`readAsArrayBuffer`). - URL в форматі base-64 (`readAsDataURL`). У багатьох випадках нам не потрібно читати увесь вміст файлу. Так же як і з blob, ми можемо створити коротке посилання за допомогою `URL.createObjectURL(file)` та присвоїти його тегу `` чи ``. Таким чином файл можна завантажити чи показати як зображення, як частину вмісту canvas тощо. Також легко відправити `File` мережею, бо мережеве API `XMLHttpRequest` чи `fetch` можуть безпосередньо працювати з об’єктами `File`.