# 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`.