前端学习笔记之FileReader

发布于:2024-11-28 ⋅ 阅读:(30) ⋅ 点赞:(0)

概念

FileReader接口允许网页应用程序异步读取用户计算机上存储的文件(或原始数据缓冲区)的内容,使用File或Blob对象来制定要读取的文件或数据。

File对象可以通过用户使用<input>元素选择文件后返回的FileList对象获得,或者来自拖放操作的DataTransfer对象。

FileReader只能访问用户明确选择的文件内容,这些文件要么是通过HTML<input type="file">元素选择的,要么是通过拖放操作选择的,它不能用来通过路径名从用户的文件系统中读取文件。

实例属性:

FileReader.error:表示在读取文件过程中发生的错误的DOMException。所谓DOMException ,就是DOMException 接口表示一种异常事件(称为异常),当调用一个方法或访问一个 Web API 的属性时会发生这种事件。这是在 Web API 中描述错误条件的方式。【简答来说就是抛出的异常,会出现各种错误名称:如:NotFoundError The object cannot be found here. 】

FileReader.readyState:表示FileReader状态的数字。

一共有三种:

名称 描述
EMPTY       0 尚未加载任何数据

LOADING

DONE

1

2

数据正在加载中

整个请求已完成

FileReader.result:文件的内容,这个属性仅仅在读取操作完成后生效,并且数据的格式取决于用于启动读取操作的方法。

实例方法

FileReader.abort():中断读取操作,返回式readyState将为DONE。

FileReader.readAsArrayBuffer():开始读取指定Blob的内容,一旦完成,result属性将包含一个表示文件数据的ArrayBuffer。

FileReader.readAsDataURL():开始读取指定Blob内容,一旦完成,result属性将包含一个表示文件的数据URL。

FileReader.readAsText():开始读取指定Blob内容,一旦完成,result属性将包含文件的内容作为文本字符串,可以指定一个可选的编码名称。

事件

使用addEventListener()或分配一个事件监听器到这个接口的oneventname属性来监听这些事件。一旦不再使用FileReader,使用removeEventListener()移除事件监听器,以避免内存泄漏。

abort:当读取操作被终止时触发。

error:当读取由于错误而失败时触发。

load:当读取成功完成时触发。

loadend:无论读取成功与否,当去读完成时触发。

loadstart:当读取开始时触发。

progress:在读取数据时定时触发。

下面以一个实例来使用上面的部分实例和方法:
代码如下:

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

<input type="file" id="fileInput" accept="image/*,video/*,audio/*,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/pdf">
<button id="downloadBtn" disabled>Download</button>
<script>
document.getElementById('fileInput').addEventListener('change', function(event) {
    var file = event.target.files[0];
    if (file) {
        document.getElementById('downloadBtn').disabled = false;

        // 使用readAsDataURL读取文件
        var reader = new FileReader();
        reader.onload = function(e) {
            // 读取完成后,直接使用DataURL作为下载链接
            var dataUrl = e.target.result;
            var blob = new Blob([e.target.result], { type: file.type });
            // 创建Blob的URL
            var url = URL.createObjectURL(blob);
            
            // 定义下载功能
            document.getElementById('downloadBtn').onclick = function() {
                // 创建一个临时<a>元素用于下载
                var link = document.createElement('a');
                // link.href = dataUrl;
                link.href = url;
                link.download = file.name;
                // 通过模拟点击链接来触发下载
                document.body.appendChild(link);
                link.click();
                // 清理临时链接
                document.body.removeChild(link);
            };
        };
        // 读取文件为DataURL
        // reader.readAsDataURL(file);
        // 读取文件为Blob对象
        reader.readAsArrayBuffer(file);
        // reader.(file);
    } else {
        document.getElementById('downloadBtn').disabled = true;
    }
});
</script>

</body>
</html>

执行结果为:

其实,该实例就是在本地上传文件后,然后点击下载按钮,该文件就会在浏览器中进行下载。

 

在做这个实例的时候也出现了一个问题,其实就是对于Blob和File的理解不清楚,因为我们需要上传的文件使用了FileReaderreadAsText方法来读取文件内容。这意味着下载的文件将包含文本数据。如果你想要保持文件的原始二进制格式,你可以改用readAsArrayBufferreadAsDataURL方法,并相应地调整Blob的构造方式。所以我们在读取的时候,如果要使用的是Blob, 那么读取的时候就要使用readAsArrayBuffer.

如果使用的是File,就是直接input type=File,而不是被Blob包裹的,就直接使用readAsDataURL即可。如果混用了,那么就会出现下面的情况:【也就是虽然文件能够下载,但是你预览不了的情况】

 

 详细的解释如下:

当我们使用 readAsDataURL 方法时,e.target.result 是一个包含文件数据的 Base64 编码的字符串(DataURL),它已经包含了文件类型(MIME 类型)和编码后的数据。因此,当我们直接将这个字符串作为链接的 href 属性时,浏览器能够正确地解析并下载文件。

然而,当我们尝试将这个 DataURL 字符串封装进一个 Blob 对象,并创建一个新的 URL 时,你实际上是在将一个已经是 Base64 编码的字符串再次当作原始二进制数据来处理。这导致最终的文件内容不正确,因此文件无法打开。

为了解决这个问题,应该使用 readAsArrayBuffer 而不是 readAsDataURL,因为 ArrayBuffer 包含的是原始的二进制数据,这些数据可以直接用于创建 Blob 对象。

Blob

Blob(Binary Large Object)对象代表了一种可以存储大量二进制数据的不可变对象。在 Web 开发中,Blob 对象通常用于处理来自文件系统或网络请求的二进制数据。Blob 对象是不可变的,这意味着一旦创建,其内容就不能被修改,但可以读取。

以下是 Blob 对象的一些关键特性和用法:

特性

  1. 不可变性:Blob 对象一旦被创建,其内容就不能更改。如果需要修改内容,必须创建一个新的 Blob 对象。

  2. 类型:Blob 对象有一个 type 属性,它是一个 MIME 类型的字符串,表示数据的类型。如果类型未知,这个属性是空字符串。

  3. 大小:Blob 对象有一个 size 属性,表示存储在 Blob 中的数据的字节大小。

  4. 分割:Blob 对象可以使用 slice() 方法进行分割,返回一个新的 Blob 对象,包含原始 Blob 对象的一部分数据。

创建 Blob 对象

Blob 对象可以通过多种方式创建,例如:

  • 使用 Blob 构造函数,传入一个包含数据的数组和一个可选的 MIME 类型字符串。
  • 通过 <input type="file"> 元素的 files 属性获取用户选择的文件。
  • 通过拖放 API 获取用户拖入的数据。

示例:

// 创建一个包含文本的 Blob 对象

var blob = new Blob(["Hello, world!"], { type: "text/plain;charset=utf-8" });

// 创建一个包含 HTML 的 Blob 对象

var blob = new Blob(["<h1>Hello, world!</h1>"], { type: "text/html;charset=utf-8" });

读取 Blob 对象

Blob 对象的数据可以通过 FileReader API 读取,或者可以使用 URL.createObjectURL() 方法创建一个指向 Blob 对象的 URL,然后将其用于 <img><video> 或 <audio> 元素。

示例:

// 使用 FileReader 读取 Blob 对象的内容

var reader = new FileReader();

reader.onload = function(event) {

var text = event.target.result;

console.log(text);

};

reader.readAsText(blob); // 创建一个指向 Blob 对象的 URL

var url = URL.createObjectURL(blob); // 使用这个 URL 作为图片的源

var img = document.createElement('img');

img.src = url;

document.body.appendChild(img);

使用 Blob 对象

Blob 对象常用于以下场景:

  • 文件上传:将 Blob 对象发送到服务器。
  • 文件下载:创建一个 Blob 对象,然后触发一个下载。
  • 数据处理:读取和操作文件内容,例如将图像转换为 Base64 编码。

Blob 对象是处理 Web 应用程序中二进制数据的核心工具,它允许开发者以灵活的方式处理文件和多媒体内容。