• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

超级飞燕

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

文件基础与文件转换

文件基础与文件转换 文件的表示形式 1.数组缓冲区 ArrayBuffer 2.二进制大对象 Blob 3.二进制字符流 BinaryString 4.二进制字节流 bytes 5.base64 DataURL 6.blobUrl objectUrl 文件各种表现形式之间的转换

文件基础

一、文件的表示形式:

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
)

文件转换

Snipaste_2022-03-18_22-28-58.png

四、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

  1. 逗号切割 base64 链接,拿到 base64 编码的源数据
  2. atob() 将 base64 解码为字节数组
  3. 创建 数组缓冲区 ArrayBuffer
  4. 用 ArrayBuffer 创建类型数组 typedArray
  5. for 循环 将字节数组的每个元素放入类型数组 typedArray 中
  6. 创建 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 });
}

微信图片_20220321161355.jpg

posted on 2022-03-21 16:22  超级飞燕  阅读(183)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3