Чтение файлов с FileReader

Последнее обновление: 13.11.2023

Для чтения выбранных файлов в File API применяется объект FileReader. Этот тип предоставляет различные методы чтения файлов:

  • readAsBinaryString(): считывает данные в строку байтов

  • readAsText(): считывает данные как текст

  • readAsDataURL(): считывает данные как URL-адреса данных. URL-адреса данных — это особая схема URL-адресов для встраивания данных в HTML-код. URL-адреса данных начинаются со строки data:, за которой следует MIME-тип и информация о кодировке, а также соответствующие закодированные данные — например, data:image/png;base64,jfdsfrRdF для изображения PNG с кодировкой Base64. Так, с помощью URL-адресов данных, например, данные изображения в виде строки можно использовать непосредственно в HTML-коде, что, в свою очередь, уменьшает количество HTTP-запросов к веб-странице, поскольку браузеру не нужно делаnm второй запрос на получение изображения

  • readAsArrayBuffer(): считывает данные в объект ArrayBuffer

  • abort(): прерывает процесс считывания данных

Также в процессе работы с FileReader могут возникать ряд событий:

  • abort: генерируется при прерывании чтения методом abort()

  • error: генерируется при возникновении ошибки

  • load: генерируется при успешном завершении чтения данных

  • loadstart: генерируется при начале процессе чтения данных

  • loadend: генерируется после завершения чтения данных

  • progress: генерируется в процессе чтения, уведомляя о прогрессе чтения

Так, при успешном завершении считывания срабатывает событие load, в обработчике которого можно получить считанные данные либо через свойство result объекта FileReader, либо через свойство target.result параметра обработчика события. ранее был заранее определен обработчик событий или зарегистрирован прослушиватель событий. Если событие загрузки было вызвано, содержимое файла также доступно через свойство result

Например, считаем файлы, которые выбираются через элемент <input type="file">. Допустим, у меня есть следующий файл "hello.txt":

Hello METANIT.COM
Hello World

Для его считывания (и для считывания любых других текстовых файлов) определим следующую веб-страницу:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
<input type="file" id="files" accept="text/*" multiple />
<script>
function printFiles(e) {  
    const files = e.target.files;   // получаем все выбранные файлы
    for (file of files) {        // Перебираем все выбранные файлы 
        // создаем объект FileReader для считывания файла
        const reader = new FileReader();  
        // при успешном чтении файла выводим его содержимое на веб-страницу
        reader.onload = () => {  
            // выводим содержимое
            console.log(reader.result);
            // для разделения, если выбрано несколько файлов
            console.log("==============================");
        };      
         // считываем файл
        reader.readAsText(file);       
    }
}
document.getElementById("files").addEventListener("change", printFiles);
</script>
</body>
</html>

Здесь на странице определен элемент ввода input, для которого с помощью атрибута accept="text/*" задан фильтр на прием только текстовых файлов

<input type="file" id="files" accept="text/*" multiple />

В коде JavaScript для элемента input в качестве обработчика события "change" устанавливаем функцию printFiles:

document.getElementById("files").addEventListener("change", printFiles);

В этой функции проходим по всем выбранным файлам, которые получаем из объекта события через свойство e.target.files, и создаем объект FileReader для считывания для каждого файла

function printFiles(e) {  
    const files = e.target.files;   // получаем все выбранные файлы
    for (file of files) {        // Перебираем все выбранные файлы 
        // создаем объект FileReader для считывания файла
        const reader = new FileReader();  
        // при успешном чтении файла выво

Определяем обработчик для события load:

reader.onload = () => {  
    console.log(reader.result); // выводим содержимое
    // для разделения, если выбрано несколько файлов
    console.log("==============================");
};  

В обработчике с помощью свойства reader.result получаем считанные данные и выводим их на консоль. Также, если выбрано несколько файлов, выводим на консоль условный разделитель.

В конце собственно считываем файл с помощью функции readAsText()

reader.readAsText(file); 

Результат работы:

Считывание текстовых файлов с помощью FileReader в JavaScript

Вывод метаданных файла

Мы посмотрели, как получить и вывести на консоль текст файла. В принципе все довольно просто. Но при переборе файлов через свойства объекта File нам доступны различные метаданные файла - имя, размер, тип, дата изменения. Что, если мы хотим, к примеру, при выводе текста файла также выводить его имя? Наивный подход выглядел бы следующим образом:

for (file of files) {
    console.log("File Name:", file.name);   // выводим имя файла
    const reader = new FileReader();
    reader.onload = () => {  
        console.log("File Name:", file.name);   // можно попробовать вывести здесь
        console.log(reader.result);
        console.log("==============================");
    };      
    reader.readAsText(file);       
}

Проблема в том, что обработчик reader.onload имеет асинхронную природу - считывание предыдущего файла может завершиться, когда начнется (или даже уже закончено) считывание следующего файла. Соответственно такой подход может привести к коллизиям. Одно из возможных решений состоит в том, что захватить нужные нам данные извне через замыкание:

function printFiles(e) {  
    const files = e.target.files;
    for (file of files) {
        
        const reader = new FileReader();
        reader.onload = (function(fileData) {
            return function(e){
                console.log("File Name:", fileData.name);
                console.log(e.target.result); // то же самое, что и reader.result
                console.log("==============================");
            };
        })(file);
        reader.readAsText(file);       
    }
}

В данном случае обработчику onload присваивается результат самовыполняющейся функции, которая образует замыкание. Через ее параметр fileData в функцию передается текущий объект File.

Считывание изображений

Аналогичным образом можно считывать и другие типы файлов. Например, считаем и выведем на веб-страницу изображения:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
    <style>
    div.item {width: 250px; margin:0 10px;}
    .image {width: 250px;}
    </style>
</head>
<body>
<input type="file" id="files" accept="image/*" multiple />
<div id="fileList"></div>
<script>
function printFiles(e) {  
    const files = e.target.files;
    for (file of files) {
        
        const reader = new FileReader();  
        reader.onload = (function(fileData) {
            return function(){
                // создаем элемент div
                const fileItem = document.createElement("div");
                fileItem.className = "fileItem";

                // создаем заголовок для добавляемого файла 
                const fileHeader = document.createElement("h3");
                fileHeader.textContent = fileData.name;
                fileItem.appendChild(fileHeader);

                // создаем элемент img для отображения файла
                const img = document.createElement("img");   
                img.src = reader.result;
                img.className = "image";       
                fileItem.appendChild(img); 
                document.getElementById("fileList").appendChild(fileItem);  
            };
        })(file);
        reader.readAsDataURL(file); 
    }
}
document.getElementById("files").addEventListener("change", printFiles);
</script>
</body>
</html>

Теперь для элемента ввода задан фильтр accept="image/*", а все загружаемые изображения отображаются в элементе <div id="fileList">. Для этого в обработчике onload создаем элемент div, в него добавляем заголовок h3 с именем файла и элемент img с содержимым файла. Содержимое файла считывается с помощью метода reader.readAsDataURL(). Пример работы:

Считывание изображений с помощью FileReader в JavaScript

Сочетание различных типов

Также можно сочетать открытие файлов различных типов:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
    <style>
    div.item {width: 250px; margin:0 10px;}
    .text{min-height: 80px; width: 250px; border:1px solid #ccc;padding:10px;}
    .image {width: 250px;}
    </style>
</head>
<body>
<input type="file" id="files" multiple />
<div id="fileList"></div>
<script>
const fileList = document.getElementById("fileList");
// создаем элемент, который представляет отдельный файл на странице
function createFileItem(file){
    const fileItem = document.createElement("div");
    fileItem.className = "fileItem";

    // создаем заголовок для добавляемого файла 
    const fileHeader = document.createElement("h3");
    fileHeader.textContent = file.name;
    fileItem.appendChild(fileHeader);
    return fileItem;
}
function readTextFile(file){
    return function(e){
        const fileItem = createFileItem(file);
        // создаем элемент div для вывода текста файла
        const div = document.createElement("div");   
        // переносы строки заменяем на соответствующий текст
        div.textContent = e.target.result.replace("\n", "\n");
        div.className = "text";       
        fileItem.appendChild(div); 
        fileList.appendChild(fileItem);  
    };
}
function readImageFile(file){
    return function(e){
        const fileItem = createFileItem(file);
        // создаем элемент img для отображения файла
        const img = document.createElement("img");   
        img.src = e.target.result;
        img.className = "image";       
        fileItem.appendChild(img); 
        fileList.appendChild(fileItem);  
    };
}
function printFiles(e) {  
    const files = e.target.files;
    for (file of files) {
        // считываем файл
        const reader = new FileReader(); 
        if(file.type.match("text.*")) {      
            reader.onload = readTextFile(file);
            reader.readAsText(file);    
        } 
        else if(file.type.match("image.*")) {      
            reader.onload = readImageFile(file);      
            reader.readAsDataURL(file);    
        }
    }
}
document.getElementById("files").addEventListener("change", printFiles);
</script>
</body>
</html>

Здесь в зависимости от того, какой тип представляет файл, создаем определенный элемент (<div> для вывода текстовых файлов и <img> для вывода изображений). К примеру, выберем файлы разных типов:

Чтение текстовых файлов и изображений с помощью FileReader в JavaScript
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850