掌握 File API 这篇就够了

掌握 File API 这篇就够了

File API 是为了让 Web 开发者能以安全的方式访问客户端机器上的文件,从而更好地与这些文件交互而设计的。

File API 提供了丰富的功能,让Web开发者能够轻松处理文件。掌握File API 首先要理解和掌握三种类型 File、FileReader和FileReaderSync。

File类型使得对上传文件的信息获取变得简单,

而FileReader类型则允许异步读取文件内容,适用于处理大文件或实现文件预览。

FileReaderSync类型则提供了在Web Workers中进行同步文件读取的机制。

File 类型

HTML5 在 DOM 上为文件输入元素添加了 files 集合。

当用户在文件字段中选择一个或多个文件时, 这个 files 集合会包含一组 File 对象, 表示被选中的文件。每个 File 对象都有一些只读属性:

  • name: 本地系统中的文件名
  • size: 以字节(Byte)计的文件大小
  • type: 包含文件 MIME 类型的字符串
  • lastModifiedDate: 表示文件最后修改时间的字符串。(仅Chrome支持)

代码示例

下面的例子描述如何使用JavaScript监听文件输入框的变化事件(change事件),并通过遍历文件列表(event.target.files)来获取每个选中文件的信息。每当用户选择文件后,通过创建动态列表项(<li>)来展示文件的名称、类型和大小。这交互式的例子通过清晰的HTML结构和JavaScript事件处理,使用户能够轻松选择文件并查看其基本信息。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>File Information Example</title>
</head>
<body>

  <!-- 文件输入框 -->
  <input type="file" id="files-list" multiple>
  <!-- 显示文件信息的列表 -->
  <p>Selected Files Information:</p>
  <ul id="file-info-list"></ul>

  <script>
    // 添加事件监听器,当文件选择发生变化时触发
    document.getElementById("files-list").addEventListener("change", (event) => {
      const filesList = event.target.files;  // 获取选中的文件列表
      const fileInfoList = document.getElementById("file-info-list");  // 文件信息列表
      
      // 清空之前的文件信息
      fileInfoList.innerHTML = "";
      
      // 遍历选中的每个文件,显示文件信息
      for (let i = 0; i < filesList.length; i++) {
        const file = filesList[i];
        const listItem = document.createElement("li");  // 创建列表项元素
        // 显示文件信息(文件名、类型、大小)
        listItem.textContent = `${file.name} (${file.type}, ${file.size} bytes)`;
        fileInfoList.appendChild(listItem);  // 将列表项添加到文件信息列表中
      }
    });
  </script>

</body>
</html>

FileReader

FileReader 类型表示一种异步文件读取机制,可以将其类比于 XMLHttpRequest,但它专门用于从文件系统异步读取文件内容,而非从服务器获取数据。FileReader 类型提供了多个方法,用于实现对文件数据的异步读取操作。

基本语法

js 复制代码
 const reader = new FileReader();

 reader.onload = () =>{}

 reader.readAsDataURL(file);

方法

  • readAsText(file, encoding) 从文件中读取纯文本内容并保存在 result 属性中。第二个参数表示编码,是可选的。
  • readAsDataURL(file) 读取文件并将内容的数据 URI 保存在 result 属性中。
  • readAsBinaryString(file) 读取文件并将每个字符的二进制数据保存在 result 属性中。
  • readAsArrayBuffer(file) 读取文件并将文件内容以 ArrayBuffer 形式保存在 result 属性。

这些读取数据的方法为处理文件数据提供了极大的灵活性。例如,为了向用户显示图片,可以将图片读取为数据 URI,而为了解析文件内容,可以将文件读取为文本。

事件

因为上面的读取方法都是异步的,所以每个 FileReader 都会发布几个事件, 其中三个最有用的事件:

  1. progress: progress 还有更多数据,每隔 50 毫秒会触发一次
  2. error: 发生了错误,属性时一个独享,包含 code 1.未找到文件 2.安全错误 3. 读取被中断 4. 文件不可读 5.编码错误
  3. load: 读取完成,文件成功加载后触发, error事件被处罚,则不会触发load事件。

使用 FileReader 读取图片

简单的Web页面允许用户选择图片文件,通过 FileReader 异步读取图片内容,并在页面上显示图片。同时,添加了一个进度条,展示文件读取的实时进度并监听错误事件。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Read and Display Image</title>
</head>
<body>

  <!-- 文件输入框 -->
  <input type="file" id="image-input">

  <!-- 显示图片 -->
  <img id="selected-image" style="max-width: 100%;">

  <!-- 进度条 -->
  <progress id="file-progress" value="0" max="100"></progress>

  <script>
    document.getElementById("image-input").addEventListener("change", (event) => {
      const selectedImage = document.getElementById("selected-image");
      const fileProgress = document.getElementById("file-progress");
      const file = event.target.files[0];

      if (file && file.type.startsWith("image")) {
        // 通过FileReader异步读取文件内容
        const reader = new FileReader();

        reader.onload = (e) => {
          // 将读取的图片数据设置为img元素的src属性,显示在页面上
          selectedImage.src = e.target.result;
          fileProgress.value = 100; // 读取完成时将进度条设为100%
        };

        reader.onprogress = (e) => {
          if (e.lengthComputable) {
            const percentLoaded = (e.loaded / e.total) * 100;
            fileProgress.value = percentLoaded; // 更新进度条
          }
        };

        reader.onerror = () => {
          alert("文件读取失败。请重新选择有效的图片文件。");
          selectedImage.src = "";  // 清空图片显示
        };

        reader.readAsDataURL(file);  // 以DataURL形式读取图片内容
      } else {
        alert("请选择有效的图片文件。");
        selectedImage.src = "";  // 清空图片显示
      }
    });
  </script>
</body>
</html>

FileReaderSync 类型

FileReaderSync 是 FileReader 类型的同步版本。拥有 FileReader 相同的方法。,只有在整个文件都加载到内存之后才会继续执行。

FileReaderSync 只在工作线程(Web Workers)中可用,因为如果读取整个文件耗时太长则会影响全局。

FileReaderSync 是一个同步的API,它主要设计用于在工作线程(Web Workers)中执行,以避免阻塞主线程。在工作线程中使用它时,不会阻塞主进程,因为工作线程是在独立于主线程的线程中运行的。

例子

假设通过 postMessage()向工作线程发送了一个 File 对象。以下代码会让工作线程同步将文件读取到内存中,然后将文件的数据 URL发回来:

js 复制代码
// worker.js
self.onmessage = (messageEvent) => {
  const syncReader = new FileReaderSync();
  // 读取文件时阻塞工作线程
  const result = syncReader.readAsDataURL(messageEvent.data);
  // PDF 文件的示例响应
  console.log(result); // data:application/pdf;base64,JVBERi0xLjOK...
  // 把URL 发回去
  self.postMessage(result);
};

结语

File API 的引入使得在浏览器环境中对客户端文件的操作更加方便和安全。通过 File、FileReader 和 FileReaderSync,开发者可以获取文件信息、异步读取文件内容以及在 Web Workers 中进行同步文件读取,从而实现更多样化的文件交互和处理操作。在实际应用中,开发者可以根据具体需求选择合适的类型和方法,以达到更好的用户体验和性能优化,如果你有独特的见解或者经验,欢迎在下方评论区分享,让大家共同学习进步。

相关推荐
Boilermaker199211 分钟前
【Java EE】SpringIoC
前端·数据库·spring
中微子23 分钟前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上102438 分钟前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y1 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁1 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry1 小时前
Fetch 笔记
前端·javascript
拾光拾趣录1 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟1 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan1 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构