一、核心概念与关系
javascript
复制代码
ArrayBuffer ──────────────────────────────────────────────────
│ 原始二进制内存,不能直接读写 │
▼ │
TypedArray / DataView ← 视图层,用于读写 ArrayBuffer │
(Uint8Array, Int32Array, Float64Array...) │
│
Blob ───── 不可变的二进制大对象,有 type(MIME) │
│ │
▼ (继承) │
File ───── 在 Blob 基础上增加 name / lastModified │
│
互转链路: │
ArrayBuffer ──► Uint8Array ──► Blob ──► File │
File / Blob ──► ArrayBuffer (通过 .arrayBuffer() 或 FileReader)
二、各类型速查
类型
可变?
直接读写?
用途
ArrayBuffer
否(需视图)
❌
原始内存容器
TypedArray
✅
✅
数值型数组操作
DataView
✅
✅
精确控制字节序(endian)
Blob
❌
❌
文件内容、网络传输
File
❌
❌
用户上传文件
三、ArrayBuffer 操作
3.1 创建
javascript
复制代码
const buf = new ArrayBuffer(16); // 分配 16 字节,全为 0
3.2 通过 TypedArray 读写
ini
复制代码
const view = new Uint8Array(buf);
view[0] = 255;
view[1] = 128;
const int32 = new Int32Array(buf);
int32[0] = 42; // 占 4 字节
const float64 = new Float64Array(buf);
float64[0] = 3.14; // 占 8 字节
3.3 通过 DataView 控制字节序
javascript
复制代码
const dv = new DataView(buf);
dv.setInt32(0, 300, true); // true = 小端(little-endian)
dv.getInt32(0, true); // 读取 → 300
dv.setFloat32(4, 1.5, false); // false = 大端(big-endian)
dv.getFloat32(4, false); // → 1.5
3.4 切片(复制新 buffer)
ini
复制代码
const sliced = buf.slice(0, 8); // 取前 8 字节,返回新 ArrayBuffer
3.5 复制 / 合并
javascript
复制代码
// 合并多个 ArrayBuffer
function concat(...buffers) {
const total = buffers.reduce((n, b) => n + b.byteLength, 0);
const result = new Uint8Array(total);
let offset = 0;
for (const b of buffers) {
result.set(new Uint8Array(b), offset);
offset += b.byteLength;
}
return result.buffer;
}
3.6 转字符串
ini
复制代码
// ArrayBuffer → UTF-8 字符串
const decoder = new TextDecoder('utf-8');
const str = decoder.decode(buf);
// 字符串 → ArrayBuffer
const encoder = new TextEncoder();
const buf2 = encoder.encode('Hello').buffer;
四、互转方法
4.1 ArrayBuffer → Blob
go
复制代码
const blob = new Blob([arrayBuffer], { type: 'application/octet-stream' });
4.2 Blob → ArrayBuffer
ini
复制代码
// 现代方式(推荐)
const buf = await blob.arrayBuffer();
// 旧方式(兼容性)
function blobToBuffer(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsArrayBuffer(blob);
});
}
4.3 Blob → File
go
复制代码
const file = new File([blob], 'example.png', {
type: 'image/png',
lastModified: Date.now(),
});
4.4 File → ArrayBuffer
csharp
复制代码
const buf = await file.arrayBuffer(); // File 继承自 Blob
4.5 ArrayBuffer → Base64
javascript
复制代码
const base64 = btoa(
String.fromCharCode(...new Uint8Array(arrayBuffer))
);
// Base64 → ArrayBuffer
const bin = atob(base64);
const buf = new Uint8Array(bin.length).map((_, i) => bin.charCodeAt(i)).buffer;
4.6 Blob → Object URL(预览/下载)
ini
复制代码
const url = URL.createObjectURL(blob);
// 用完释放
URL.revokeObjectURL(url);
4.7 Blob → 文本
vbnet
复制代码
const text = await blob.text();
const json = JSON.parse(await blob.text());
五、常用场景示例
5.1 读取用户上传文件
ini
复制代码
input.addEventListener('change', async (e) => {
const file = e.target.files[0]; // File 对象
const buffer = await file.arrayBuffer(); // → ArrayBuffer
const view = new Uint8Array(buffer);
console.log(view[0], view[1]); // 读取头两字节
});
5.2 下载二进制数据
ini
复制代码
const response = await fetch('/api/file');
const buffer = await response.arrayBuffer();
const blob = new Blob([buffer], { type: 'application/pdf' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = 'result.pdf';
a.click();
URL.revokeObjectURL(a.href);
5.3 修改图片二进制头(示例:读 PNG 宽高)
ini
复制代码
const buf = await file.arrayBuffer();
const dv = new DataView(buf);
// PNG: 宽在偏移 16,高在偏移 20(大端)
const width = dv.getUint32(16, false);
const height = dv.getUint32(20, false);
5.4 WebSocket 发送 / 接收二进制
ini
复制代码
ws.binaryType = 'arraybuffer';
ws.onmessage = (e) => {
const view = new Uint8Array(e.data); // 直接是 ArrayBuffer
};
// 发送
ws.send(new Uint8Array([0x01, 0x02, 0x03]).buffer);
go
复制代码
const form = new FormData();
form.append('file', file); // File 对象
// 或用 Blob + 指定文件名
form.append('file', blob, 'data.bin');
await fetch('/upload', { method: 'POST', body: form });
六、关系总图(文字版)
typescript
复制代码
用户选文件
│
▼
File (name, lastModified, type)
│ 继承
▼
Blob (不可变, type)
│
├─ .arrayBuffer() ──► ArrayBuffer ──► TypedArray / DataView (读写字节)
├─ .text() ──► string
├─ .stream() ──► ReadableStream
└─ URL.createObjectURL() ──► blob:// URL ──► <img src> / <a download>
ArrayBuffer
├─ new Blob([buf]) ──► Blob
├─ new Uint8Array(buf) ──► TypedArray(视图)
├─ new DataView(buf) ──► DataView(视图)
└─ TextDecoder.decode(buf) ──► string
七、兼容性提示
API
兼容性
blob.arrayBuffer()
Chrome 76+, Firefox 69+, Node 15+
blob.text()
同上
FileReader
全浏览器,旧项目兼容方案
TextEncoder/Decoder
现代浏览器 & Node 11+
ArrayBuffer.transfer()
Chrome 114+(零拷贝转移所有权)