文件基础与文件转换
文件基础
一、文件的表示形式:
1. 数组缓冲区 ArrayBuffer
字节数组 bytedArray 数组缓冲区 ArrayBuffer(用来存放字节数组的缓冲区)
ArrayBuffer(12782)
2. 二进制大对象 Blob
blob:Blob {size: 12782, type: 'image/png'}
3. 文件 File
File : File {name: 'avatar.webp', lastModified: 1646204612494, lastModifiedDate: Wed Mar 02 2022 15:03:32 GMT+0800 (中国标准时间), webkitRelativePath: '', size: 12782, type: "image/webp",webkitRelativePath: ""}
4. 二进制字符流 BinaryString
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
5. 二进制字节流 bytes
RIFFæ1 WEBPVP8 Ú1 ÐÛ
6. base64 DataURL
data:image/webp;base64,UklGRuYxAABXRUJQVlA4IN
7. blobUrl objectUrl
blob:http://localhost:8080/83c2e21a-08d6-4e22-a662-868e7f64d66e
二、文件格式之间的关系
base64 和二进制字节流之间的关系:
base64 是用字符串形式表示二进制
base64 字符串 是使用 base64 编码规则,将二进制编码为 base64 字符串
文件的二进制是固定不变的,编码后的 base64 字符串也是固定不变的
base64 字符串和 bolobUrl 之间的关系:
base64 和 blobUrl 都是一个链接
base64 是永久不变的,blobUrl 是临时链接,用完之后是要销毁的
base64 可以在浏览器地址栏直接打开,也可以作为 src 属性的属性值
blobUrl 在链接销毁之前可以在浏览器打开,也可以作为 src 属性的属性值
blob 和 file 的关系:
blob 二进制大对象
file 是基于 blob 的文件对象,file 在 blob 的基础上进行扩展,使其支持用户系统上的文件。
三、ArrayBuffer
ArrayBuffer 对象用来表示通用的,固定长度的原始二进制数据缓冲区
。。。。。。。。|。。。。。。。。|。。。。。。。。|
它是一个字节数组,在其它语言中称为 byte array。 即数组的每一项都是一个字节,一个字节占 8 位
不能直接操作 ArrayBuffer 的内容,而是要通过类型数组 TypedArray 对象或者 DataView 对象来操作。它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容
// 创建一个长度为8个字节发buffer
const buffer = new ArrayBuffer(8) // 参数为字节数
console.log(buffer.byteLength) // 获取字节数组的字节长度
TypedArray
TypedArray 描述了一个底层的二进制数据缓冲区(binary data buffer)的一个类数组视图(view)
它本身不可以被实例化,甚至不可以被访问,你可以把它理解为接口,他有很多实现
类型 | 单个元素的范围 | 大小(byte) | 描述 |
---|---|---|---|
Int8Array | -128~127 | 1 | 8 位二进制有符号整数 |
Uint8Array | 0~255 | 1 | 8 位无符号整数 |
Int16Array | -32768~32767 | 2 | 16 位二进制有符号整数 |
Uint16Array | 0~65535 | 2 | 16 位无符号整数 |
const buffer = new ArrayBuffer(10) // 10个字节的数组缓冲区
const int16Array = new Int16Array(buffer) // 变为16位二进制有符号整数。即两个字节代表一个数组元素
console.log(int16Array.length) // 5
DataView
DataView 是一个可以从 ArrayBuffer 对象中 读写多种数值类型的底层接口
setInt8(a,b) 从 DataView 起始位置开始 以 a byte 为指定偏移量处 存储一个 8bit 数
getInt16(a) 从 DataView 起始位置开始 以 a byte 为指定偏移量处 获取一个 16bit 数
const buffer = new ArrayBuffer(10) // 10个字节的数组缓冲区
const dataView = new DataView(buffer)
dataView.setInt8(0, 2)
dataView.setInt8(1, 2)
console.log(
dataView.getInt8(0), //2
dataView.getInt8(1), //2
dataView.getInt16(0), //514
dataView.getInt8(1), //2
)
文件转换
四、Blob
Blob 对象表示一个不可变的,原始数据的类文件对象。File 接口基于 Blob,继承了 Blob 并对其进行扩展,使其支持用户系统上的文件。
ArrayBuffer to blob
let blob = new Blob([arryBuffer], { type: 'image/png' })
blob to ArrayBuffer/DataURL/BinaryString/Text
// FileReader将Blob读成各种文件
function readBlob(blob,type){
return new Promise(function(resolve){
let reader=new FileReader()
reader.onload=function(event){
resolve(event.target.result)
}
switch(type){
case 'ArrayBuffer': // 将blob读成ArrayBuffer
reader.readAsArrayBuffer(blob)
break
case 'DataURL': // 将blob读成DataURL
reader.readAsDataURL(blob)
break
case 'BinaryString': // 将blob读成BinaryString
reader.readAsBinaryString(blob)
break
case 'Text': // 将blob读成Text
reader.readAsText(blob)
break
default:
break
}
五、File
File to base64
let file = obj.files[0] //获取文件
function fileToBase64(file) {
let reader = new FileReader() //实例化文件读取对象
reader.readAsDataURL(file) //将文件读取为 DataURL,也就是base64编码
reader.onload = function (ev) {
//文件读取成功完成时触发onload
let base64Str = ev.target.result //获得文件读取成功后的DataURL,也就是base64编码
console.log(base64Str) // 打印文件的base64码
}
}
file to ArrayBuffer/DataURL/BinaryString/Text
function readFile(file,type){
return new Promise(function(resolve){
let reader=new FileReader()
reader.onload=function(event){
resolve(event.target.result)
}
switch(type){
case 'ArrayBuffer': // 将file读成ArrayBuffer
reader.readAsArrayBuffer(file)
break
case 'DataURL': // 将file读成DataURL
reader.readAsDataURL(file)
break
case 'BinaryString': // 将file读成BinaryString
reader.readAsBinaryString(file)
break
case 'Text': // 将file读成Text
reader.readAsText(file)
break
default:
break
}
File、blob 转 blobUrl
bloburl 不可以在浏览器地址栏中使用
base64 可以在浏览器地址栏使用,有更好 的移植性
const url = URL.createObjectURL(file) // 为blob数据创建objectURL地址
console.log(url) // blob:http://localhost:8080/83c2e21a-08d6-4e22-a662-868e7f64d66e
this.showUploadImg = url // 可用于临时展示获取到的图片
URL.remokeObjectURL(blob) // 回收blobURL地址,回收之后blobUrl链接不可用
三、base64 编码格式
编码: btoa() 方法 将文件字节流编码为 base64
解码: atob() 方法 将 base64 解码为文件字节流
文件的编码解码:
图片等文件 在计算机中是以 字节数组的形式存储在数组缓冲区中的
图片在计算机中就是一个字节数组(一堆看不懂的字符)
使用 btoa()将字节数组转换为 base64 字符串,base64 字符串可以使用 img 标签展示
// base64Url为文件的base64URL
const bytes = atob(base64Url.split(',')[1])
文本的编码解码:
普通的 Text 文本,如:hello
可以使用 btoa() 将文本编码成 base64 字符串
使用 atob() 将 base64 字符串解码为文本 hello
【注意】上传不建议使用 base64,因为 base64 比较大
同一个图片,base64 字符串比二进制大三分之一
因此最好使用二进制上传
// bytes为文件的二进制字节流
const base64Url = atob(bytes)
base64 转 blob
base64->bytesStr->ArrayBuffer->blob
- 逗号切割 base64 链接,拿到 base64 编码的源数据
- atob() 将 base64 解码为字节数组
- 创建 数组缓冲区 ArrayBuffer
- 用 ArrayBuffer 创建类型数组 typedArray
- for 循环 将字节数组的每个元素放入类型数组 typedArray 中
- 创建 blob 对象,将 ArrayBuffer 作为参数传入
得到了 blob 对象
function base64ToBlob() {
let base64Str = dataUrl.split(',')[1]
let bytes = atob(base64Str)
let arrayBuffer = new ArrayBuffer(bytes.length)
let uInt8Array = new Uint8Array(arrayBuffer)
for (let i = 0; i < bytes.length; i++) {
uInt8Array[i] = bytes.charCodeAt[i]
}
let blob = new Blob([arrayBuffer], { type: 'image/png' })
}
base64 转 File
base64->bytesStr->ArrayBuffer->file
base64toFile(dataurl, filename) { // 生成Blob
var arr = dataurl.split(',');
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
let arra
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)