Blob,ArrayBuffer,Base64区别
大约 5 分钟
Blob、ArrayBuffer 和 Base64 的区别
基本概念区别
Blob (Binary Large Object)
- 定义: 表示一个不可变的、原始数据的类文件对象
- 特点: 用于表示二进制数据,可以直接用于文件操作
- 本质: 浏览器特定的对象,主要用于Web API
ArrayBuffer
- 定义: 表示一个通用的、固定长度的原始二进制数据缓冲区
- 特点: 纯二进制数据,需要通过视图(如
Uint8Array) 来操作 - 本质: 通用的二进制数据容器
Base64
- 定义: 一种基于64个可打印字符来表示二进制数据的编码方式
- 特点: 将二进制数据编码为ASCII字符串
- 本质: 一种编码格式,不是数据结构
数据操作方式区别
| 特性 | Blob | ArrayBuffer | Base64 |
|---|---|---|---|
| 可直接操作数据 | 否 | 否(需通过视图) | 是(字符串) |
| 可修改数据 | 否(不可变) | 否(需创建新缓冲区) | 是(字符串可修改) |
| 大小效率 | 高效 | 高效 | 较低(增加约33%) |
| 内存使用 | 较少 | 较少 | 较多(字符串存储) |
使用场景区别
Blob 主要用于:
- 文件操作(上传、下载、预览)
- 与浏览器API交互
- 媒体数据处理
ArrayBuffer 主要用于:
- 低级二进制数据操作
- WebGL、音频处理
- 网络协议实现
- 高性能计算
Base64 主要用于:
- 文本格式传输二进制数据
- 嵌入资源到文本格式(HTML、CSS、JSON)
- URL和邮件传输
相互转换示例
// Blob 转 ArrayBuffer
function blobToArrayBuffer(blob) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.readAsArrayBuffer(blob);
});
}
// ArrayBuffer 转 Base64
function arrayBufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
let binary = '';
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
// Base64 转 ArrayBuffer
function base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}
// ArrayBuffer 转 Blob
function arrayBufferToBlob(buffer, type) {
return new Blob([buffer], { type });
}
// Blob 转 Base64
function blobToBase64(blob) {
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result.split(',')[1]);
reader.readAsDataURL(blob);
});
}性能和内存考虑
Blob:
- 内存效率高
- 适合大文件操作
- 支持流式处理
ArrayBuffer:
- 内存效率最高
- 适合高性能计算
- 直接操作内存
Base64:
- 内存开销大(约增加33%)
- 适合小数据文本传输
- 不适合大文件处理
选择建议
- 处理文件或与浏览器API交互时: 使用
Blob - 进行底层二进制操作或高性能计算时: 使用
ArrayBuffer - 需要在文本环境中传输二进制数据时: 使用
Base64
Blob、ArrayBuffer 和 Base64 的使用场景详解
Blob (Binary Large Object)
Blob 表示一个不可变的、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取。
使用场景:
文件上传和下载
- 在 Web 应用中处理用户上传的文件
- 从服务器下载文件并保存到本地
图片预览
- 在上传图片前在浏览器中预览
- 使用
URL.createObjectURL()创建临时 URL
音视频处理
- 处理媒体文件,如录音、录像等
- 创建媒体元素的源数据
示例代码:
// 文件上传示例
function handleFileUpload(file) {
const blob = new Blob([file], { type: file.type });
// 可以直接上传 blob 到服务器
uploadToServer(blob);
}
// 图片预览示例
function previewImage(file) {
const blob = new Blob([file], { type: 'image/jpeg' });
const imageUrl = URL.createObjectURL(blob);
document.getElementById('preview').src = imageUrl;
}ArrayBuffer
ArrayBuffer 表示一个通用的、固定长度的原始二进制数据缓冲区。它不能直接操作数据,需要通过 TypedArray 或 DataView 来操作。
使用场景:
WebGL 和图形处理
- 处理顶点数据、纹理数据等
- 与 GPU 进行数据交换
音视频编解码
- 处理原始音频样本数据
- 视频帧数据处理
网络协议实现
- 实现自定义二进制协议
- 处理 WebSocket 二进制数据
加密和哈希计算
- 对原始数据进行加密操作
- 计算文件的哈希值
示例代码:
// 处理音频数据示例
function processAudioData() {
const buffer = new ArrayBuffer(16); // 16字节缓冲区
const int16Array = new Int16Array(buffer);
// 填充音频样本数据
for (let i = 0; i < int16Array.length; i++) {
int16Array[i] = Math.sin(i * 0.1) * 0x7FFF;
}
// 发送到音频处理API
audioContext.decodeAudioData(buffer);
}
// WebSocket 二进制数据处理
websocket.onmessage = function(event) {
if (event.data instanceof ArrayBuffer) {
const view = new DataView(event.data);
const firstByte = view.getUint8(0);
// 处理二进制协议
}
};Base64
Base64 是一种基于64个可打印字符来表示二进制数据的编码方式。它将3个字节的二进制数据编码为4个字符。
使用场景:
内联图片
- 将小图片编码为 Base64 直接嵌入 HTML 或 CSS 中
- 减少 HTTP 请求次数
数据传输
- 在 JSON 中传输二进制数据
- 在 URL 中传递二进制数据
邮件附件编码
- MIME 协议中编码附件数据
- 邮件正文中的嵌入图片
本地存储
- 在 localStorage 中存储小的二进制数据
- 配置文件中嵌入资源
示例代码:
// 图片转 Base64
function imageToBase64(file) {
const reader = new FileReader();
reader.onload = function(event) {
const base64String = event.target.result;
// 使用 base64 字符串
document.getElementById('image').src = base64String;
};
reader.readAsDataURL(file);
}
// Base64 转 Blob
function base64ToBlob(base64String, contentType = '') {
const byteString = atob(base64String.split(',')[1]);
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], { type: contentType });
}
// 在 CSS 中使用 Base64
const cssWithBase64 = `
.icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==');
}
`;三者之间的转换关系
// Blob 转 ArrayBuffer
function blobToArrayBuffer(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(reader.error);
reader.readAsArrayBuffer(blob);
});
}
// ArrayBuffer 转 Base64
function arrayBufferToBase64(buffer) {
let binary = '';
const bytes = new Uint8Array(buffer);
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
// Base64 转 ArrayBuffer
function base64ToArrayBuffer(base64) {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
return bytes.buffer;
}这三种数据格式在前端开发中各有其用途,选择哪种取决于具体的应用场景和需求。