Skip to content

FileReader

[TOC]

索引

属性

  • reader.resultstring|ArrayBuffer|null只读,访问读取结果
  • reader.errorDOMException|null,用于获取文件读取过程中发生的错误信息
  • reader.readyState0|1|2只读,获取当前读取状态

方法

  • new FileReader()()构造函数,创建一个新的 FileReader 实例。
  • reader.readAsText()(file,encoding?),以文本形式异步读取文件内容。
  • reader.readAsDataURL()(file),将文件内容转换为 Base64 编码的 Data URL,可直接用于嵌入网页(如图片预览)。
  • reader.readAsArrayBuffer()(file),将文件内容读取为 ArrayBuffer 对象(二进制数据的底层容器),用于直接操作二进制数据。
  • reader.abort()(),立即中止正在进行的文件读取操作。

事件

  • loadevent,读取成功完成时触发。

  • errorevent,当读取由于错误而失败时触发。

  • abortevent,当读取被中止时触发,例如因为程序调用了 FileReader.abort() 方法。

  • progressevent,读取数据时持续触发。

  • loadendevent,读取完成时触发,无论成功与否。

  • loadstartevent,读取开始时触发。

FileReader

属性

result

reader.resultstring|ArrayBuffer|null只读,访问读取结果

  • 返回:

  • resultstring|ArrayBuffer|null,具体返回类型取决于调用的读取方法:

    • string:调用 readAsText() 或 readAsDataURL() 返回的类型。
    • ArrayBuffer:调用 readAsArrayBuffer() 返回的类型。
    • null:未调用读取方法或读取失败返回的类型。

语法特性

  1. 异步获取结果

    • result 仅在读取操作完成后(触发 onload 事件)才包含有效值。
    • onload 事件外直接访问 result 可能得到 null
    js
    const reader = new FileReader();
    reader.onload = function(e) {
      console.log(e.target.result); // 正确:在 onload 中获取结果
    };
    reader.readAsText(file);
    console.log(reader.result); // 错误:此时尚未完成读取,结果为 null
  2. 读取状态依赖

    • 若读取过程中调用 abort() 或发生错误(触发 onerror),resultnull
    • 可通过 readyState 判断当前状态:0(未开始)、1(读取中)、2(完成)。
  3. 二进制数据处理ArrayBuffer 需转换为具体类型(如 Uint8Array)才能操作:

    js
    reader.onload = function(e) {
      const buffer = e.target.result;
      const uint8Array = new Uint8Array(buffer);
      console.log(uint8Array);
    };
    reader.readAsArrayBuffer(file);

error

reader.errorDOMException|null,用于获取文件读取过程中发生的错误信息

  • 返回:

  • errorDOMException|null,返回值类型和含义如下:

    • DOMException{name,message},读取过程中发生错误。
    • null:读取成功或未发生错误。

语法特性

  1. 错误类型(DOMException.name)

    错误类型触发场景
    NotFoundError文件未找到(如用户取消选择文件后尝试读取)。
    SecurityError文件被浏览器标记为不安全(如跨域文件未经允许)。
    AbortError读取操作被 abort() 方法中止。
    NotReadableError文件无法读取(如文件损坏或权限问题)。
    EncodingError编码错误(如 readAsText() 指定了不支持的编码格式)。
  2. 错误处理必要性:必须监听 onerror 事件以捕获潜在错误,否则用户可能无法感知读取失败:

    js
    reader.onerror = function(e) {
      alert(`读取失败: ${e.target.error.message}`);
    };
  3. 异步错误捕获:错误信息仅在触发 onerror 事件后有效。在事件外直接访问 error 可能为 null

    js
    reader.readAsText(file);
    console.log(reader.error); // ❌ 此时可能尚未触发错误,结果为 null
  4. 状态关联性:错误发生后,readyState 变为 2DONE)。

  5. 错误重置:每次调用新的读取方法(如 readAsText())时,error 会被重置为 null

示例

  1. 监听错误事件并获取错误信息

    js
    const reader = new FileReader();
    
    reader.onerror = function(e) {
      const error = reader.error; // 或 e.target.error
      console.error("错误类型:", error.name); // 错误类型: NotReadableError
      console.error("错误描述:", error.message); // 错误描述: The file could not be read.
    };
    
    reader.readAsText(file); // 假设此操作因文件问题失败

readyState

reader.readyState0|1|2只读,获取当前读取状态

  • 返回:

  • state0|1|2默认:0,返回当前读取操作的状态。

    • 0常量名:EMPTY未开始读取。此时尚未调用任何读取方法,或读取已被重置。
    • 1常量名:LOADING数据正在加载中。读取操作已开始但未完成(如 onprogress 事件触发期间)。
    • 2常量名:DONE读取操作已完成(无论成功、失败或中止)。此时可通过 resulterror 获取结果。

语法特性

  1. 状态流转
    1. 初始状态:创建 FileReader 实例时,readyState 默认为 0EMPTY)。
    2. 读取开始:调用 readAsText()readAsDataURL() 等方法后,状态变为 1LOADING)。
    3. 读取结束:操作完成(成功、失败或中止)后,状态变为 2DONE)。
  2. 与事件的关系
    • onloadstart:当状态从 01 时触发。
    • onprogress:当状态为 1 时周期性触发。
    • onload / onerror / onabort:当状态从 12 时触发。
    • onloadend:无论成功与否,状态变为 2 后触发。
  3. 状态不可逆:一旦进入 DONE 状态,readyState 不会自动重置为 EMPTY。需重新创建 FileReader 实例以进行新的读取。

示例

  1. 监听状态变化

    js
    const reader = new FileReader(); // 初始状态为 0
    
    // 监听状态变化(通过事件间接判断)
    reader.onloadstart = function(e) {
      console.log("状态: LOADING (1)");
    };
    
    reader.onload = function(e) {
      console.log("状态: DONE (2)");
      console.log("结果:", e.target.result);
    };
    
    reader.readAsText(file); // 触发状态变化 0 → 1
  2. 判断是否可安全操作

    js
    if (reader.readyState === 1) {
      console.log("读取正在进行,不可调用新操作");
    } else {
      reader.readAsDataURL(newFile); // 安全调用新读取
    }

方法

new FileReader()

new FileReader()()构造函数,创建一个新的 FileReader 实例。

  • 返回:

  • readerFileReader,返回一个 FileReader 实例对象,用于后续文件读取操作。

语法特性

  1. 同步操作

    • 每个 FileReader 实例同一时间只能处理一个读取操作
    • 若需要并发读取多个文件,需为每个文件创建独立的 FileReader 实例:
    js
    // 并发读取多个文件
    files.forEach(file => {
      const reader = new FileReader(); // 每个文件单独实例
      reader.onload = (e) => { /* 处理结果 */ };
      reader.readAsText(file);
    });
  2. 内存管理:读取大文件(如视频)时,result 属性会占用较大内存,操作完成后建议手动释放引用:

    js
    reader.onload = function(e) {
      const data = e.target.result;
      // 处理数据...
      reader.result = null; // 释放内存(可选)
    };
  3. 错误处理:必须监听 onerror 事件以捕获可能的读取失败:

    js
    reader.onerror = function(e) {
      console.error("错误类型:", e.target.error.name);
      console.error("错误信息:", e.target.error.message);
    };

示例

  1. 基本用法

    js
    // 1. 创建 FileReader 实例
    const reader = new FileReader();
    
    // 2. 监听加载完成事件
    reader.onload = function(e) {
      console.log("读取结果:", e.target.result);
    };
    
    // 3. 选择文件并读取(例如通过 <input type="file">)
    const fileInput = document.querySelector('input[type="file"]');
    fileInput.addEventListener('change', function(e) {
      const file = e.target.files[0];
      reader.readAsText(file); // 以文本形式读取文件
    });

readAsText()

reader.readAsText()(file,encoding?),以文本形式异步读取文件内容。

  • fileFile|Blob,要读取的文件对象(通常通过 <input type="file"> 或拖放操作获取)。

  • encoding?string默认:UTF-8,指定文本编码格式。

  • 返回:

  • resultundefined,异步方法,没有直接返回值。读取结果通过 FileReaderonload 事件获取(存储在 result 属性中)。

语法特性

  1. 结果获取

    • 成功读取:通过 onload 事件监听器访问 result(类型为 string):

      js
      const reader = new FileReader();
      reader.onload = function(e) {
        const textContent = e.target.result; // 字符串形式的文件内容
        console.log(textContent);
      };
      reader.readAsText(file); // 触发读取操作
    • 失败处理:通过 onerror 监听错误:

      js
      reader.onerror = function(e) {
        console.error("读取失败:", e.target.error);
      };
  2. 编码支持:默认使用 UTF-8 编码,但支持其他常见编码(如 "ASCII""ISO-8859-1")(Safari 对非 UTF-8 编码的支持有限)。

  3. 异步操作

    • 读取过程非阻塞,需通过事件监听获取结果。

    • 可通过 onprogress 监听读取进度:

      js
      reader.onprogress = function(e) {
        const percent = (e.loaded / e.total) * 100;
        console.log(`已读取: ${percent.toFixed(2)}%`);
      };
  4. 中断读取:调用 abort() 可终止读取:

    js
    reader.abort(); // 中断后触发 onabort 事件
  5. 文件类型限制

    • 适用于文本文件(.txt, .csv, .json 等),读取二进制文件(如图片)可能得到乱码。
    • 二进制文件建议使用 readAsArrayBuffer()readAsDataURL()
  6. 大文件处理:超大文本文件可能导致内存压力,需结合 onprogress 分阶段处理。

示例

  1. 读取文本文件

    html
    <input type="file" id="fileInput">
    
    <script>
      document.getElementById("fileInput").addEventListener("change", function(e) {
        const file = e.target.files[0];
        const reader = new FileReader();
    
        reader.onload = function(e) {
          console.log("文件内容:", e.target.result);
        };
    
        reader.readAsText(file); // 默认 UTF-8 编码
      });
    </script>
  2. 指定编码读取

    js
    reader.readAsText(file, "ISO-8859-1"); // 使用 Latin-1 编码

readAsDataURL()

reader.readAsDataURL()(file),将文件内容转换为 Base64 编码的 Data URL,可直接用于嵌入网页(如图片预览)。

  • fileFile|Blob,要读取的文件对象(通过 <input type="file"> 或拖放操作获取的文件)。

  • 返回:

  • resultundefined,异步方法,没有直接返回值。读取结果通过 FileReaderonload 事件获取(存储在 result 属性中)。

语法特性

  1. 结果获取

    • 读取成功:通过 onload 事件监听器访问 result(类型为 string,格式为 Data URL)。

      js
      const reader = new FileReader();
      reader.onload = function(e) {
        const dataURL = e.target.result; // 示例:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."
        console.log(dataURL);
      };
      reader.readAsDataURL(file); // 触发读取操作
    • 失败处理:通过 onerror 监听错误:

      js
      reader.onerror = function(e) {
        console.error("读取失败:", e.target.error);
      };
  2. Data URL 格式

    • 格式data:[<mediatype>][;base64],<data>
      • mediatype:文件的 MIME 类型(如 image/pngtext/plain)。
      • base64:标识数据采用 Base64 编码。
      • data:文件内容的 Base64 字符串。
    • 示例data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...
  3. 适用场景

    • 图片预览:直接作为 <img><canvas>src

      js
      reader.onload = function(e) {
        document.getElementById("preview").src = e.target.result;
      };
    • 文件内容嵌入网页(如 PDF 预览、音频播放)。

  4. 异步操作

    • 读取过程非阻塞,需通过事件监听获取结果。

    • 可通过 onprogress 监听读取进度:

      js
      reader.onprogress = function(e) {
        const percent = (e.loaded / e.total) * 100;
        console.log(`已读取: ${percent.toFixed(2)}%`);
      };
  5. 中断读取:调用 abort() 可终止读取:

    js
    reader.abort(); // 中断后触发 onabort 事件
  6. 文件大小限制:Data URL 是文件的 Base64 编码,体积比原始文件大 约 33%。大文件谨慎使用。

  7. 安全性:Base64 编码的 Data URL 可能被恶意利用(如 XSS 攻击),需避免处理不可信来源的文件。

  8. 内存释放:读取完成后,可手动释放 result 属性以节省内存:

    js
    reader.onload = function(e) {
      const dataURL = e.target.result;
      // 使用数据...
      reader.result = null; // 释放内存(可选)
    };

示例

  1. 读取图片预览

    js
    <input type="file" id="fileInput">
    <img id="preview" src="" alt="预览">
    
    <script>
      document.getElementById("fileInput").addEventListener("change", function(e) {
        const file = e.target.files[0];
        const reader = new FileReader();
    
        reader.onload = function(e) {
          document.getElementById("preview").src = e.target.result;
        };
    
        reader.readAsDataURL(file); // 转换为 Data URL
      });
    </script>
  2. 读取文本文件

    js
    // 读取 .txt 文件,Data URL 的 mediatype 为 "text/plain"
    reader.readAsDataURL(file);

readAsArrayBuffer()

reader.readAsArrayBuffer()(file),将文件内容读取为 ArrayBuffer 对象(二进制数据的底层容器),用于直接操作二进制数据。

  • fileFile|Blob,要读取的文件对象(通过 <input type="file"> 或拖放操作获取的文件)。

  • 返回:

  • resultundefined,异步方法,没有直接返回值。读取结果通过 FileReaderonload 事件获取(存储在 result 属性中)。

语法特性

  1. 结果获取

    • 成功读取后,通过 onload 事件监听器访问 result(类型为 ArrayBuffer):

      js
      const reader = new FileReader();
      reader.onload = function(e) {
        const arrayBuffer = e.target.result; // ArrayBuffer 对象
        console.log(arrayBuffer);
      };
      reader.readAsArrayBuffer(file); // 触发读取操作
    • 失败处理:通过 onerror 监听错误:

      js
      reader.onerror = function(e) {
        console.error("读取失败:", e.target.error);
      };
  2. 二进制数据操作ArrayBuffer 是固定长度的二进制数据容器,需通过 TypedArray(如 Uint8Array)或 DataView 操作具体数据:

    js
    reader.onload = function(e) {
      const buffer = e.target.result;
      const uint8Array = new Uint8Array(buffer); // 转换为 Uint8Array
      console.log("二进制数据:", uint8Array);
    };
  3. 适用场景

    • 图像处理(如像素级操作)。
    • 文件分片上传(如大文件切割后逐块上传)。
    • 加密/解密二进制数据。
    • 解析自定义二进制格式(如 .zip.png 等)。
  4. 异步操作:同 readAsDataURL / readAsText

  5. 中断读取:同 readAsDataURL / readAsText

  6. 文件大小限制ArrayBuffer 直接存储文件原始二进制数据,大文件可能占用大量内存,需合理分片处理。

  7. 内存释放:读取完成后,可手动释放 result 属性以节省内存:

    js
    reader.onload = function(e) {
      const buffer = e.target.result;
      // 处理数据...
      reader.result = null; // 释放内存(可选)
    };

示例

  1. 读取图片并转换为二进制数组

    html
    <input type="file" id="fileInput">
    
    <script>
      document.getElementById("fileInput").addEventListener("change", function(e) {
        const file = e.target.files[0];
        const reader = new FileReader();
    
        reader.onload = function(e) {
          const buffer = e.target.result;
          const uint8Array = new Uint8Array(buffer);
          console.log("二进制数据:", uint8Array);
        };
    
        reader.readAsArrayBuffer(file);
      });
    </script>
  2. 分片上传伪代码

    js
    const chunkSize = 1024 * 1024; // 1MB 分片
    let offset = 0;
    
    function uploadNextChunk(file) {
      const chunk = file.slice(offset, offset + chunkSize);
      const reader = new FileReader();
      
      reader.onload = function(e) {
        const buffer = e.target.result;
        // 将 buffer 上传到服务器
        fetch("/upload", { method: "POST", body: buffer });
        offset += chunkSize;
        if (offset < file.size) uploadNextChunk(file);
      };
    
      reader.readAsArrayBuffer(chunk);
    }
    
    uploadNextChunk(largeFile);

abort()

reader.abort()(),立即中止正在进行的文件读取操作。

  • 返回:

  • resultundefined,没有返回值,但调用后会触发 onabort 事件,并将 readyState 设为 2DONE

语法特性

  1. 中止行为

    • 中止后,FileReaderresult 属性被重置为 null
    • 若读取操作尚未开始(readyState0),调用 abort() 无效。
    • 若读取已开始但未完成(readyState1),中止操作并触发 onabort 事件,并将 readyState 设为 2
  2. 事件触发:调用 abort() 后,会依次触发以下事件:

    1. onabort:表示读取操作被中止。

    2. onloadend:表示读取流程结束(无论成功、失败或中止)。

  3. 状态管理

    • 调用 abort() 后,FileReader 实例的 readyState 变为 2DONE),无法继续使用该实例进行新操作。

    • 需重新创建 FileReader 实例以进行新的读取:

      js
      reader.abort();
      reader = new FileReader(); // 重新实例化
      reader.readAsText(file);   // 重新读取
  4. 错误处理:中止操作不会触发 onerror 事件,但若中止时发生错误(如文件损坏),仍需监听 onerror

    js
    reader.onerror = function(e) {
      console.error("错误:", e.target.error);
    };
  5. 应用场景

    • 用户主动取消:提供“取消”按钮,允许用户中止耗时的大文件读取。
    • 超时中断:设置读取超时,超时后自动中止操作。
    • 内存优化:在读取大文件时,若检测到内存不足,主动中止以避免崩溃。

示例

  1. 基础用法

    js
    const reader = new FileReader();
    
    // 开始读取操作
    reader.readAsText(file);
    
    // 中途中止
    setTimeout(() => {
      reader.abort(); // 中止读取
    }, 1000); // 假设 1 秒后中止
    
    // 监听中止事件
    reader.onabort = function(e) {
      console.log("读取操作已中止");
    };
    
    // 监听结束事件
    reader.onloadend = function(e) {
      console.log("读取流程结束");
    };
  2. 结合用户交互(如取消按钮)

    html
    <input type="file" id="fileInput">
    <button id="cancelBtn">取消读取</button>
    
    <script>
      let reader;
    
      document.getElementById("fileInput").addEventListener("change", function(e) {
        const file = e.target.files[0];
        reader = new FileReader();
    
        reader.onload = function(e) {
          console.log("读取结果:", e.target.result);
        };
    
        reader.onabort = function(e) {
          console.log("用户取消了读取");
        };
    
        reader.readAsText(file);
      });
    
      // 点击按钮中止读取
      document.getElementById("cancelBtn").addEventListener("click", function() {
        if (reader && reader.readyState === 1) {
          reader.abort();
        }
      });
    </script>

事件

  • loadevent,读取成功完成时触发。

  • errorevent,当读取由于错误而失败时触发。

  • abortevent,当读取被中止时触发,例如因为程序调用了 FileReader.abort() 方法。

  • progressevent,读取数据时持续触发。

  • loadendevent,读取完成时触发,无论成功与否。

  • loadstartevent,读取开始时触发。