Appearance
前端二进制2
ArrayBuffer
ArrayBuffer
对象代表储存二进制数据的一段内存,它不能直接读写,只能通过视图进行操作。
// 创建一个长度为 16 的 buffer 它会分配一个 16 字节(byte)的连续内存空间,并用 0 进行预填充。
const buffer1 = new ArrayBuffer(16);
复制代码
TypedArray
TypedArray是一组构造函数,一共包含九种类型,每一种都是一个构造函数。
TypedArray的构造函数接受三个参数,第一个ArrayBuffer(其实还可以是数组、视图这里不细说)对象,第二个视图开始的字节号(默认0),第三个视图结束的字节号(默认直到本段内存区域结束)。
名称 | 占用字节 | 描述 |
---|---|---|
Int8Array | 1 | 8位有符号整数 |
Uint8Array | 1 | 8位无符号整数 |
Uint8ClampedArray | 1 | 8位无符号整型固定数组(数值在0~255之间) |
Int16Array | 2 | 16位有符号整数 |
Uint16Array | 2 | 16位无符号整数 |
Int32Array | 4 | 32 位有符号整数 |
Uint32Array | 4 | 32 位无符号整数 |
Float32Array | 4 | 32 位 IEEE 浮点数 |
Float64Array | 8 | 64 位 IEEE 浮点数 |
// Uint8Array —— 将 ArrayBuffer 中的每个字节视为 0 到 255 之间的单个数字(每个字节是 8 位)。这称为 “8 位无符号整数”。
// Uint16Array —— 将每 2 个字节视为一个 0 到 65535 之间的整数。这称为 “16 位无符号整数”。
// Uint32Array —— 将每 4 个字节视为一个 0 到 4294967295 之间的整数。这称为 “32 位无符号整数”。
// Float64Array —— 将每 8 个字节视为一个 5.0x10-324 到 1.8x10308 之间的浮点数。
const uint8 = new Uint8Array(buffer1);
const uint16 = new Uint16Array(buffer1);
const uint32 = new Uint32Array(buffer1);
const float64 = new Float64Array(buffer1);
复制代码
DataView
DataView
就是一种更灵活的视图,DataView视图支持除Uint8ClampedArray以外的八种类型。DataView比使用TypedArray更方便,只需要简单的创建一次就能进行各种转换。
// 可以转成各种格式
const dataView1 = new DataView(buffer1);
console.log(dataView1);
console.log(dataView1.getUint8(0));
console.log(dataView1.getUint16(0));
console.log(dataView1.getUint32(0));
console.log(dataView1.getFloat64(0));
复制代码
Blob
Blob
对象表示一个不可变、原始数据的类文件对象。
// 构造函数
const blob = new Blob(array, options)
复制代码
- array 是一个由
ArrayBuffer, ArrayBufferView, Blob, DOMString
等对象构成的数组,DOMStrings
会被编码为UTF-8。 - options 是一个可选,它可能会指定如下两个属性:
- type,默认值为
""
,内容的MIME类型。 - endings,默认值为
"transparent"
,用于指定包含行结束符\n
的字符串如何被写入。 它是以下两个值中的一个:"native"
,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者"transparent"
,代表会保持blob中保存的结束符不变
- type,默认值为
const blob1 = new Blob(['hello randy'], { type: "text/plain" });
复制代码
实例属性、方法
属性
type
类型 常见的MIME 类型size
大小、单位为字节
const blob = new Blob(["hello", "randy"], { type: "text/plain" });
// 输出的对象有如下属性
// size: 10;
// type: "text/plain";
console.log(blob);
复制代码
方法
slice()
从Blob
中截取一部分并返回一个新的Blob
(用法同数组的slice
)arrayBuffer()
返回一个以二进制形式展现的promise
stream()
返回一个ReadableStream
对象text()
返回一个文本形式的promise
// 转成stream
console.log(blob.stream());
// 转成Arraybuffer
blob.arrayBuffer().then((res) => {
console.log(res);
});
// 转成文本
blob.text().then((res) => {
console.log(res);
});
复制代码
blob url
简单的理解一下就是将一个file
或Blob
类型的对象转为UTF-16
的字符串,并保存在当前操作的document
下,存储在内存中。
生成blob url使用的方法是URL.createObjectURL(file/blob)
。清除方式只有页面unload()
事件或者使用URL.revokeObjectURL(objectURL)
手动清除 。
这在前端下载中经常会用到。
export const downloadFile = async (params, fileName) => {
// 我们使用axios设置接口返回类型 responseType: "blob", 所以这里从后端返回的是blob。
const results = await download(params);
const a = document.createElement("a");
a.download = fileName + ".xlsx";
// 生成blob url。这里可以使用Blob对象或者File对象
a.href = window.URL.createObjectURL(results);
a.style.display = "none";
document.body.appendChild(a);
a.click();
// 释放内存
window.URL.revokeObjectURL(a.href);
document.body.removeChild(a);
};
复制代码
File
File
描述文件信息的一个对象,可以让 JavaScript
访问文件信息。File
继承于 Blob
。
const file = new File(array, name[, options])
复制代码
- array 是一个由
ArrayBuffer, ArrayBufferView, Blob, DOMString
等对象构成,DOMStrings
会被编码为UTF-8。 - name 表示文件名称,或者文件路径。
- options 是一个可选,它可能会指定如下两个属性:
- type,默认值为
""
,内容的MIME类型。 - lastModified: 数值,表示文件最后修改时间的 Unix 时间戳(毫秒)。默认值为 Date.now()。
- type,默认值为
实例属性、方法
属性
type
类型 常见的MIME 类型size
大小、单位为字节name
文件名称lastModified
最后修改时间(时间戳)lastModifiedDate
最后修改时间
const file1 = new File(["文件对象"], "test", { type: "text/plain" });
// 输出的对象有如下属性
// lastModified: 1640589621358
// lastModifiedDate: Mon Dec 27 2021 15:20:21 GMT+0800 (中国标准时间) {}
// name: "test"
// size: 12
// type: "text/plain"
// webkitRelativePath: ""
console.log(file1);
复制代码
方法
slice()
从Blob
中截取一部分并返回一个新的Blob
(用法同数组的slice
)arrayBuffer()
返回一个以二进制形式展现的promise
stream()
返回一个ReadableStream
对象text()
返回一个文本形式的promise
// 转成stream
console.log(file1.stream());
// 转成Arraybuffer
file1.arrayBuffer().then((res) => {
console.log(res);
});
// 转成文本
file1.text().then((res) => {
console.log(res);
});
复制代码
Base64
定义
Base64是一种编码格式,在前端经常会碰到,格式是 data:[<mediatype>][;base64],<data>
。
除了使用工具进行Base64编码外,js还内置了两个方法能进行字符串的Base64的编码和解码。
const str1 = "hello randy";
// 编码
const b1 = window.btoa(str1);
console.log(b1); // aGVsbG8gcmFuZHk=
// 解码
const str2 = window.atob(b1);
console.log(str2); // hello randy
复制代码
Blob转Base64
const blob = new Blob(["hello", "randy"], { type: "text/plain" });
const fileReader = new FileReader();
fileReader.readAsDataURL(blob);
fileReader.onload = () => {
console.log(fileReader.result); // "data:text/plain;base64,aGVsbG9yYW5keQ=="
};
复制代码
优点
- 可以将二进制数据(比如图片)转化为可打印字符,方便传输数据。
- 对数据进行简单的加密,肉眼是安全的。
- 如果是在html或者css处理图片,可以减少http请求。
缺点
- 内容编码后体积变大, 至少大1/3。因为是三字节变成四个字节,当只有一个字节的时候,也至少会变成三个字节。
- 编码和解码需要额外工作量。
FileReader
FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容.
属性
属性 | 描述 |
---|---|
FileReader.error | 一个DOMException,表示在读取文件时发生的错误 。 |
FileReader.result | 返回文件的内容。只有在读取操作完成后,此属性才有效,返回的数据的格式取决于是使用哪种读取方法来执行读取操作的。 |
FileReader.readyState | 表示FileReader状态的数字。0 还没有加载任何数据。1 数据正在被加载。2 已完成全部的读取请求。 |
方法
需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result属性中。
方法名 | 描述 |
---|---|
FileReader.abort() | 中止读取操作。在返回时,readyState 属性为 DONE。 |
FileReader.readAsArrayBuffer() | 将读取的内容转成ArrayBuffer。 |
FileReader.readAsBinaryString() | 将读取的内容转成二进制数据。 |
FileReader.readAsDataURL() | 将读取的内容转成并将其编码为 base64 的 data url。 格式是 data:[<mediatype>][;base64],<data> |
FileReader.readAsText() | 将数据读取为给定编码(默认为 utf-8 编码)的文本字符串。 |
事件
事件 | 描述 |
---|---|
FileReader.onabort | 处理 abort 事件。该事件在读取操作被中断时触发。 |
FileReader.onerror | 处理 error 事件。该事件在读取操作发生错误时触发。 |
FileReader.onload | 处理 load 事件。该事件在读取操作完成时触发。 |
FileReader.onloadstart | 处理 loadstart 事件。该事件在读取操作开始时触发。 |
FileReader.onloadend | 处理 loadend 事件。该事件在读取操作结束时(要么成功,要么失败)触发。 |
FileReader.onprogress | 处理 progress 事件。该事件在读取Blob时触发。 |
例子
const blob3 = new Blob(["hello", "randy"], { type: "text/plain" });
const fileReader = new FileReader();
fileReader.readAsDataURL(blob3);
fileReader.onload = () => {
console.log(fileReader);
// 通过fileReader获取结果
// fileReader.result 是结果(如果成功)
// fileReader.error 是 error(如果失败)。
};
复制代码
相互转换
Blob和File的互相转换
Blob转File
const blob1 = new Blob(["blob文件"], { type: "text/plain" });
// blob转file
const file2 = new File([blob1], "test2", { type: blob1.type });
console.log("file2: ", file2);
复制代码
File转Blob
const file1 = new File(["文件对象"], "test", { type: "text/plain" });
// file转blob
const blob2 = new Blob([file1], { type: file1.type });
console.log("blob2: ", blob2);
复制代码
File、Blob、img转Base64
Blob转Base64
// Blob转Base64
const blob = new Blob(["hello", "randy"], { type: "text/plain" });
const fileReader = new FileReader();
fileReader.readAsDataURL(blob);
fileReader.onload = () => {
console.log(fileReader.result); // "data:text/plain;base64,aGVsbG9yYW5keQ=="
};
复制代码
File转Base64
// File转Base64
const file1 = new File(["文件对象"], "test", { type: "text/plain" });
const fileReader = new FileReader();
fileReader.readAsDataURL(file1);
fileReader.onload = () => {
console.log(fileReader); // "data:text/plain;base64,5paH5Lu25a+56LGh"
};
复制代码
img转Base64
// 本地图片转base64,注意链接是本地链接不能是网络地址。
const img2base64 = (imgUrl) => {
let image = new Image();
image.src = imgUrl;
return new Promise((resolve) => {
image.onload = () => {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
let dataUrl = canvas.toDataURL("image/png");
resolve(dataUrl);
};
});
};
img2base64("../vue2/src/assets/logo.png").then((res) => {
console.log(res);
});
复制代码
Base64转Blob、File
Base64转Blob
function dataURLtoBlob(dataurl) {
// `data:[<mediatype>][;base64],<data>`
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], { type: mime });
}
复制代码
Base64转File
function dataURLtoFile(dataurl, filename) {
//将base64转换为文件
var arr = dataurl.split(","),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
复制代码