前端系列之:Blob

前端系列之:Blob

Blob 与二进制

什么是二进制?

二进制是计算机数据的基本表示形式,只使用 0 和 1 两个数字来表示数值。任何类型的数据(无论是文本、图片、音频文件等)都可以通过二进制表示。

什么是 Blob?

全称 Binary Large Object,二进制类型的大对象。是一种数据类型,用来存储二进制数据。

怎么解释 JavaScript 的数据类型中并没有 Blob 类型?

Blob 是用来存储二进制数据的,而二进制又是计算机的基本表示形式,所以很多编程语言(如 java)和数据库(如 mysql)都是支持 Blobl 的。

但对于前端 Blob 而言,Blob 是由浏览器环境(或类浏览器环境,如 WebView 或 React Native)提供的,而不是 JavaScript 语言本身的一部分。Blob 是 Web API 的一部分,用于表示不可变的二进制数据。所以 Blob 对象只有在浏览器环境中才能正常使用。如果在非浏览器环境(如 Node.js 环境)中,默认情况下是没有 Blob 对象的。

Blob 表示不可变的、原始的二进制数据。这句话怎么理解?

“不可变” 表示一旦 Blob 对象被创建,其内容就不能被修改。如果你需要修改 Blob 中的数据,通常的做法是创建一个新的 Blob 对象,而不是直接更改原始的 Blob 对象。

Blob 用途

数据库:在数据库中,Blob 用来存储图像、音频文件等二进制数据。例如,关系型数据库中的 BLOB 类型字段用来保存图像或其他多媒体文件。

文件存储:Blob 通常用于大文件(如视频、音频、图像等)的存储,并且通常以二进制格式存在。

Web 开发(本文重点):

上传文件到服务器。

从服务器下载文件。

在浏览器中生成文件并下载。

处理图片、视频等二进制数据。

Blob 构造函数

要从其他非 Blob 对象和数据构造一个 Blob,需要使用 Blob() 构造函数。Blob 对象一旦创建,其内容不可更改。

let blob = new Blob(array, options);

array:这是一个数组,可以包含多个数据部分,通常是 ArrayBuffer(二进制数据)、Array(字符串数据)等。

options:一个可选对象

type:指定 Blob 对象的 MIME 类型。MIME 类型是一种标准,用于表示文档、文件或字节流的性质和格式。例如,"text/plain" 表示纯文本文件,"image/jpeg" 表示 JPEG 格式的图片。如果没指定,默认是 "" 空字符串。

endings:指定在创建 Blob 对象时如何处理换行符。它有两个可选值:

transparent(默认值):不转换换行符,保留原始数据中的换行符。

native:将换行符转换为当前操作系统的本地换行符(例如,在 Windows 上是 \r\n,在 Unix/Linux 上是 \n)。

示例:

let text = "Hello, world!";

let blob = new Blob([text], { type: "text/plain" });

let url = URL.createObjectURL(blob);

let a = document.createElement("a");

a.href = url;

a.download = "hello.txt";

a.click();

URL.revokeObjectURL(url)

Blob 属性/方法

属性/方法描述size获取 Blob 的大小(字节数)type获取 Blob 的类型(MIME类型)slice()Blob 分片。当你处理大文件时,可能需要将文件拆分成多个小块进行处理或上传。该方法可以让你提取文件的一部分并进行操作stream()返回一个 ReadableStream 对象,读取它将返回包含在 Blob 中的数据arrayBuffer()返回一个 ReadableStream 对象,读取它将返回包含在 Blob 中的数据

slice():Blob 分片,其有三个参数:

start:设置切片的起点,即切片开始位置。默认值为 0,即从第一个字节开始

end:设置切片的结束点,会对该位置之前的数据进行切片。默认值为blob.size

contentType:设置新 blob 的 MIME 类型。如果省略 type,则默认为 blob 的原始值

let text = "Hello, world!";

let blob = new Blob([text], { type: "text/plain" });

const subBlob = blob.slice(0, 5);

let url = URL.createObjectURL(subBlob);

let a = document.createElement("a");

a.href = url;

a.download = "hello.txt";

a.click();

URL.revokeObjectURL(url)

// 此时下载的文件内容只有 Hello

Blob 与 URL

这里只介绍 URL.createObjectURL(blob); 方法。

创建一个 Blob 对象后,我们可以使用 createObjectURL 方法将其转换为 URL 地址。该 URL 可以用于在浏览器中显示图片、下载文件等。

createObjectURL 注意事项:

使用完 URL 后,需要手动释放,否则会导致内存泄漏 URL.revokeObjectURL(url);

IE 浏览器不支持 createObjectURL 方法

下载文件上完整示例:

api.downloadFile(params).then(res=>{

let blob = new Blob([res.result]);

if (window.navigator.msSaveOrOpenBlob) {

// 兼容 IE

window.navigator.msSaveOrOpenBlob(blob, 'hello.txt');

} else {

let url = window.URL.createObjectURL(blob);

let a = document.createElement("a");

a.href = url;

a.download = "hello.txt";

document.body.appendChild(a)

a.click();

document.body.removeChild(a)

window.URL.revokeObjectURL(url)

}

})

Blob 与 Base64

Base64 可以将二进制数据转换为为 ASCII 字符串。这样可以方便地在文本协议(如 HTTP、JSON)中传输二进制数据(实际传输的是字符串)。

// 将字符串编码为 Base64:

const text = 'Hello, world!';

const base64String = btoa(text);

console.log(base64String); // 输出 Base64 编码的字符串

// 将 Base64 字符串解码为原始字符串:

const decodedText = atob(base64String);

console.log(decodedText); // 输出 'Hello, world!'

// 通过 FileReader 将 Blob 转换为 Base64 字符串:

const blob = new Blob(['Hello, world!'], { type: 'text/plain' });

const reader = new FileReader();

reader.onloadend = function() {

const base64String = reader.result.split(',')[1]; // 获取 Base64 部分

console.log(base64String);

};

reader.readAsDataURL(blob);

区别BlobBase64存储方式Blob 用于存储原始的二进制数据Base64 是将二进制数据转为文本编码的字符串性能直接存储二进制数据,不会占用额外的空间,因此它处理大文件时性能更好会增加约 33% 的数据大小,因为每个 3 字节的二进制数据会被编码为 4 字节的 Base64 字符串应用场景适合处理文件上传/下载适合将二进制数据嵌入到 HTML 或 JavaScript 中(如图片在 HTML 中的嵌入)

Blob 与 ArrayBuffer

Blob 和 ArrayBuffer 都是用于处理二进制数据。ArrayBuffer 是底层的二进制数据存储容器,而 Blob 是一种更高级的类文件对象,它可以包含 ArrayBuffer。

ArrayBuffer 适合处理小块的二进制数据,因为它在内存中是连续存储的,读写速度较快。但如果数据量过大,可能会导致内存占用过高。

Blob 更适合处理大文件或流式数据,因为它不需要将整个数据加载到内存中。浏览器可以对 Blob 进行优化,例如分块读取和处理数据,从而减少内存占用。

ArrayBuffer 特点:

存储原始的二进制数据。

长度固定,创建后无法更改。

需要通过视图(如 Uint8Array、DataView 等)来读写数据。

在实际开发中,它们的使用场景常常是互补的。 ArrayBuffer 用于在内存中高效地处理和操作二进制数据,而 Blob 则更适合用于文件的存储、传输和展示等场景。 例如,在处理图片数据时,先将图片数据读取到 ArrayBuffer 中进行处理(如裁剪、压缩等),然后再将处理后的 ArrayBuffer 转换为 Blob 对象,通过 URL.createObjectURL() 生成临时 URL 展示图片或进行文件下载。

ArrayBuffer 转 Blob:当你有一个 ArrayBuffer 并且想把它当作一个文件来处理(比如下载、上传等)时,可以将其转换为 Blob 对象。

const buffer = new ArrayBuffer(16);

// 创建一个包含 ArrayBuffer 数据的 Blob 对象

const blob = new Blob([buffer], { type: 'application/octet-stream' });

Blob 转 ArrayBuffer:当你需要对 Blob 中的数据进行底层操作时,可以将 Blob 转换为 ArrayBuffer。通常使用 FileReader 对象来完成这个转换。

const text = 'Hello, World!';

const blob = new Blob([text], { type: 'text/plain' });

const reader = new FileReader();

reader.readAsArrayBuffer(blob);

reader.onload = function() {

const buffer = reader.result;

console.log(buffer);

};

Blob 与 File

File 是 Blob 的一个子类,扩展了 Blob 的功能。它不仅包含数据本身,还包含文件的元数据(如文件名、类型等)。

在 JavaScript 中,主要有两种方法来获取 File 对象:

元素上选择文件后返回的 FileList 数组,该数组的每个元素都是一个 File 对象

文件拖放操作生成的 DataTransfer 对象

打印内容同上。

Blob 与 Streams

Blob 的局限性:Blob 对象是一次性读取整个数据,对于大文件来说,可能会占用大量的内存,导致性能问题。

Stream(数据流)是一种按顺序读取和写入数据的方式,通常用于处理大量数据而不将其一次性加载到内存中。Streams 可以通过分块逐步传输数据,使得程序能够在处理数据时节省内存资源。

使用场景:

文件读取与写入:流被广泛应用于文件的处理,尤其是当文件很大,不能一次性加载到内存时,流式处理可以分段读取并处理数据。

网络传输:流用于数据的实时传输,尤其是在处理音视频流、网络请求响应等场景下。

处理大数据:Stream 能够在读取大数据时逐块处理,而不是将整个数据加载到内存中,这样能节省内存并提高效率。

特点:

数据按块(chunk)逐步传输。

节省内存,特别适用于大文件的读取与写入。

异步操作,有助于处理 I/O 操作。

Blob 与 FileReader

FileReader 是一个用于异步读取 Blob 或 File 对象中内容的 API,并且可以将 Blob/File 读取为不同的格式(如文本、Base64 等)。

示例:

上传的文件就是最开始的 hello.txt。

FileReader 方法/事件

Web API > FileReader

方法描述readAsArrayBuffer()开始读取指定的 Blob 中的内容,一旦完成,result 属性中将包含一个表示文件数据的 ArrayBuffer 对象。readAsBinaryString()…result 属性中将包含一个表示文件中的原始二进制数据的字符串。readAsDataURL()…result 属性中将包含一个表示文件数据的 data: URLreadAsText()…result 属性中将包含一个表示所读取的文件内容的字符串

事件描述abort该事件在读取操作被中断时触发error该事件在读取操作发生错误时触发load该事件在读取操作完成时触发loadend读取完成时触发,无论成功与否loadstart读取开始时触发progress读取数据时定期触发

← 上一篇: $天首3(NQ400151)$ 天首,3年可以涨10倍吗? ——简析天首的未来之路 上周三,天首旗下天池钼矿52%股权拍...
下一篇: 《魔兽世界》wlk恶魔布刷取位置详细介绍 →

相关推荐