Skip to content
О сайте Блог Обучение Исследовать узоры Case studies
Содержание
  • Современный API доступа к файловой системе
  • Классический способ работы с файлами
  • Выбор файлов
    • Элемент ввода HTML
    • Пользовательское перетаскивание
    • А как насчет каталогов?
  • Чтение метаданных файла
  • Чтение содержимого файла
    • Отслеживайте процесс чтения файла
  • Home
  • All articles

Чтение файлов средствами JavaScript

Как выбирать файлы, читать метаданные и содержимое файлов, а также отслеживать прогресс чтения.

Jun 18, 2010 — Обновлено Mar 29, 2021
Available in: English, Español, Português, 中文, 日本語 и 한국어
Kayce Basques
Kayce Basques
TwitterGitHubGlitchHomepage
Pete LePage
Pete LePage
TwitterGitHubGlitchHomepage
Thomas Steiner
Thomas Steiner
TwitterGitHubGlitchHomepage
Содержание
  • Современный API доступа к файловой системе
  • Классический способ работы с файлами
  • Выбор файлов
    • Элемент ввода HTML
    • Пользовательское перетаскивание
    • А как насчет каталогов?
  • Чтение метаданных файла
  • Чтение содержимого файла
    • Отслеживайте процесс чтения файла

Возможность выбирать файлы на локальном устройстве пользователя и взаимодействовать с ними — это одна из наиболее часто используемых функций Интернета. С помощью этой функции пользователи могут выбирать файлы и загружать их на сервер, например, загружать фотографии или подавать налоговую отчетность и т. д. Кроме того, функция также позволяет сайтам читать файлы и управлять ими без необходимости передачи данных по сети.

Современный API доступа к файловой системе #

API доступа к файловой системе обеспечивает простой способ чтения и записи файлов и каталогов в локальной системе пользователя. В настоящее время он доступен в большинстве браузеров на основе Chromium, таких как Chrome или Edge. Чтобы узнать больше об этом, прочитайте статью «API доступа к файловой системе».

Поскольку API доступа к файловой системе еще не совместим со всеми браузерами, обратите внимание на вспомогательную библиотеку browser-fs-access, которая использует новый API везде, где это возможно, но возвращается к устаревшим подходам, если API недоступен.

Классический способ работы с файлами #

В этом руководстве показано, как:

  • выбрать файлы
    • с использованием элементов ввода HTML;
    • с использованием области перетаскивания;
  • прочитать метаданные файла;
  • прочитать содержимое файла.

Выбор файлов #

Элемент ввода HTML #

Самый простой способ разрешить пользователям выбирать файлы — это использовать элемент <input type="file">, который поддерживается во всех основных браузерах. После щелчка он позволяет пользователю выбрать один файл или несколько файлов, если включен атрибут multiple, используя встроенный в операционную систему пользовательский интерфейс выбора файлов. Когда пользователь завершает выбор файла или файлов, срабатывает событие элемента change. Вы можете получить доступ к списку файлов из event.target.files, который представляет собой объект FileList. Каждый элемент в FileList является объектом File.

<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
Проверьте, является ли метод window.showOpenFilePicker() жизнеспособной альтернативой для вашего варианта использования, поскольку он также дает дескриптор файла, чтобы вы могли записывать обратно в файл, помимо чтения. Для этого метода можно применять полизаполение.

В этом примере пользователь может с помощью встроенного в операционную систему пользовательского интерфейса выбора файлов выбрать несколько файлов, которые затем записываются в консоль.

Ограничьте типы файлов, которые пользователь может выбрать #

В некоторых случаях вы можете захотеть ограничить типы файлов, которые могут выбирать пользователи. Например, приложение для редактирования изображений должно принимать только изображения, а не текстовые файлы. Для этого вы можете добавить accept к элементу ввода, чтобы указать, какие файлы принимаются.

<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">

Пользовательское перетаскивание #

В некоторых браузерах элемент <input type="file"> также является объектом-приёмником, что позволяет пользователям перетаскивать файлы в приложение. Но объект-приёмник мал, поэтому это неудобно. Вместо этого, после предоставления базовой функциональности с помощью <input type="file">, предоставьте большую настраиваемую область перетаскивания.

Проверьте, является ли метод DataTransferItem.getAsFileSystemHandle() жизнеспособной альтернативой для вашего варианта использования, поскольку он также дает дескриптор файла, чтобы вы могли записывать обратно в файл, помимо чтения.

Выберите область перетаскивания #

Область объекта-приёмника зависит от дизайна вашего приложения. Вы можете захотеть, чтобы только часть окна была областью перетаскивания, или, возможно, всё окно.

Скриншот Squoosh, веб-приложения для сжатия изображений.
В Squoosh всё окно стает областью перетаскивания.

Squoosh позволяет пользователю перетаскивать изображение в любом месте окна, а щелчок по значку выбора изображения вызывает элемент <input type="file">. Что бы вы ни выбрали в качестве объекта-приёмника, убедитесь, что пользователю понятно, что он может перетаскивать файлы в эту область.

Определите область перетаскивания #

Чтобы включить элемент в зону перетаскивания, необходимо прослушать два события, dragover и drop. Событие dragover обновляет пользовательский интерфейс браузера, чтобы визуально показать, что действие перетаскивания создает копию файла. Событие drop запускается после того, как пользователь опускает файлы на область перетаскивания. Аналогично элементу ввода, вы можете получить доступ к списку файлов из event.dataTransfer.files, который представляет собой объект FileList. Каждый элемент в FileList является объектом File.

const dropArea = document.getElementById('drop-area');

dropArea.addEventListener('dragover', (event) => {
event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});

dropArea.addEventListener('drop', (event) => {
event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});

События event.stopPropagation() и event.preventDefault() останавливают поведение браузера по умолчанию и позволяют вместо этого запускаться вашему коду. Без них браузер ушел бы с вашей страницы и открывал файлы, которые пользователь поместил в окно браузера.

Посмотрите живую демонстрацию настраиваемой области перетаскивания.

А как насчет каталогов? #

К сожалению, на сегодня нет хорошего способа получить доступ к каталогу.

Атрибут webkitdirectory элемента <input type="file"> позволяет пользователю выбрать каталог или каталоги. Он поддерживается некоторыми браузерами на основе Chromium и, возможно, настольной версией Safari, но имеются противоречивые сведения о совместимости с другими браузерами.

Проверьте, является ли метод window.showDirectoryPicker() жизнеспособной альтернативой для вашего варианта использования, поскольку он также дает дескриптор каталога, чтобы вы могли записывать обратно в каталог, помимо чтения. Для этого метода можно применять полизаполнение.

Если перетаскивание включено, пользователь может попытаться перетащить каталог в область перетаскивания. Когда запускается событие drop, оно будет включать File для каталога, но не сможет получить доступ ни к одному из файлов в каталоге.

Чтение метаданных файла #

Объект File содержит ряд свойств метаданных о файле. Большинство браузеров предоставляют имя файла, размер файла и тип MIME, хотя в зависимости от платформы разные браузеры могут предоставлять различную или дополнительную информацию.

function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}

Вы можете увидеть это в действии в демонстрации Glitch input-type-file.

Чтение содержимого файла #

Чтобы прочитать файл, используйте объект FileReader, который позволяет читать содержимое File в память. Вы можете указать для объекта FileReader методы чтения файлов ArrayBuffer, dataURL или text.

function readImage(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('image/')) {
console.log('File is not an image.', file.type, file);
return;
}

const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}

В приведенном выше примере считывается предоставленный пользователем File, затем он преобразуется в Data URL, который используется для отображения изображения в элементе img. Ознакомьтесь с примером на Glitch read-image-file, чтобы узнать, как проверить, выбрал ли пользователь файл изображения.

Отслеживайте процесс чтения файла #

При чтении больших файлов будет целесообразно предоставлять определенный интерфейс UX, показывающий насколько далеко продвинулось чтение. Для этого используйте событие progress, предоставляемое FileReader. Событие progress предоставляет два свойства: количество почитанного loaded и общий объем чтения total.

function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});

reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}

Главное изображение взято у Vincent Botta на Unsplash

Хранение данных
Последнее обновление: Mar 29, 2021 — Улучшить статью
Return to all articles
Поделиться
подписаться

Contribute

  • Сообщить об ошибке
  • Просмотреть исходный код

Дополнительная информация

  • developer.chrome.com
  • Новости Chrome
  • Разборы конкретных случаев
  • Подкасты
  • Шоу

Соцсети

  • Twitter
  • YouTube
  • Google Developers
  • Chrome
  • Firebase
  • Google Cloud Platform
  • Все продукты
  • Условия и конфиденциальность
  • Правила сообщества

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies.