其他分享
首页 > 其他分享> > web二进制(string ----> Blob -----> (ArrayBuffer 、DataURL、ObjectURL、Text)相互转换)

web二进制(string ----> Blob -----> (ArrayBuffer 、DataURL、ObjectURL、Text)相互转换)

作者:互联网

文章目录

一、文章参考

  1. 玩转前端二进制

二、常见对象

在这里插入图片描述

2.1 存放数据的容器:ArrayBuffer(字节)

2.1.1 概念

ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。

它是一个字节数组,通常在其他语言中称为“byte array”。

你不能直接操作 ArrayBuffer 的内容,而是要通过 TypedArray 或 DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。

2.1.2 构造函数 new ArrayBuffer(length)

2.1.3 操作二进制数据的工具:DataView& TypedArray

Arraybuffer 中的内容是不能直接操作的,需要通过 TypedArray 和 DataView 对象来操作

2.1.3.1 TypedArray

函数名解释
new Int8Array();
new Uint8Array();
new Uint8ClampedArray();
new Int16Array();
new Uint16Array();
new Int32Array();
new Uint32Array();
new Float32Array();
new Float64Array();

2.1.3.2 DataView 读写多种数值类型

读 函数

函数说明
DataView.prototype.getInt8()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处获取一个8-bit数(一个字节).
DataView.prototype.getUint8()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处获取一个8-bit数(无符号字节).
DataView.prototype.getInt16()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处获取一个16-bit数(短整型).
DataView.prototype.getUint16()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处获取一个16-bit数(无符号短整型).
DataView.prototype.getInt32()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(长整型).
DataView.prototype.getUint32()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(无符号长整型).
DataView.prototype.getFloat32()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(浮点型).
DataView.prototype.getFloat64()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处获取一个64-bit数(双精度浮点型).

写 函数

函数说明
DataView.prototype.setInt8()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(一个字节).
DataView.prototype.setUint8()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(无符号字节).
DataView.prototype.setInt16()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(短整型).
DataView.prototype.setUint16()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(无符号短整型).
DataView.prototype.setInt32()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(长整型).
DataView.prototype.setUint32()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(无符号长整型).
DataView.prototype.setFloat32()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(浮点型).
DataView.prototype.setFloat64()从DataView起始位置以byte为计数的指定偏移量(byteOffset)处储存一个64-bit数(双精度浮点型).

2.1.4 案例

  1. TypedArray 相同内存不同类型读取结果不一致
'use strict';
// ArrayBuffer 不能直接操作,需要 DataView或者 TypeArray
const buffer = new ArrayBuffer(8);
// 8个字节的ArrayBuffer, 8 * 8 = 64 个bit位
console.log(buffer.byteLength); // 8

const int8Array = new Int8Array(buffer);
// 元素长度 1 个字节,占用 8 位
console.log(int8Array.length);

const int16Array = new Int16Array(buffer);
// 元素长度 2 个字节,占用 4 位
console.log(int16Array.length); // 4
  1. DataView 自由读取多种数值类型
'use strict';
// ArrayBuffer 不能直接操作,需要 DataView或者 TypeArray
// 创建2 个字节的ArrayBuffer
const buffer = new ArrayBuffer(2);

console.log(buffer.byteLength);

const dataView = new DataView(buffer);
dataView.setInt8(0, 1); // 设置第一个字节 为1,即 00000001 (二进制)
dataView.setInt8(1, 2); // 设置第二个字节 为2,即 00000010 (二进制)

console.log(dataView.getInt8(0)); // 1, asscii 码值
console.log(dataView.getInt8(1)); // 2, asscii 码值

// 去两个字节的值 258
// 00000001 00000010 (二进制)
console.log(dataView.getInt16(0));

// DataView 和 TypeArray 内部引用了buffer
console.log(dataView.buffer === buffer);
  1. UTF8转Base64(编码转换)
'use strict';
const { Buffer } = require('buffer');

// 默认是 UTF8 编码
console.log(new Buffer.from('黄彪').toString('base64')); // 6buE5b2q

console.log(new Buffer.from('6buE5b2q', 'base64').toString()); // 黄彪

2.2 Blob

2.2.1 概念

Blob 对象表示一个不可变、原始数据的类文件对象。
Blob 表示的不一定是JavaScript原生格式的数据
Blob是用来支持文件操作的

2.2.2 构造函数 Blob( array, options )

2.2.3 属性

2.2.4 方法

var textPromise = blob.text();
blob.text().then(text => /* 执行的操作…… */);
var text = await blob.text();

与 FileReader 的 readAsText() 的区别

Blob.text() 返回的是一个 promise 对象,而 FileReader.readAsText() 是一个基于事件的 API。
Blob.text() 总是使用 UTF-8 进行编码,而 FileReader.readAsText() 可以使用不同编码方式,取决于 blob 的类型和一个指定的编码名称。

2.2.5 应用场景

  1. 文件下载

通过URL.createObjectURL(blob)生成的Blob URL,赋值给a.download属性

  1. 图片展示

通过URL.createObjectURL(blob)生成的Blob URL,赋值给img.src属性

  1. 分片上传

通过blob.slice可以分割二进制数据为子Blob上传

  1. 本地读取文件

Filereader的API可以将Blob或File转化为文件ArrayBuffer/DataURL

2.3 FileReader

2.3.1 概念

允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据

2.3.2 构造方法 new FileReader()

没有参数

2.3.3 属性

value说明
EMPTY0还没有加载任何数据
LOADING1数据正在被加载
DONE2已完成全部的读取请求

2.3.4 事件处理

事件名说明
FileReader.onabort处理abort事件。该事件在读取操作被中断时触发。
FileReader.onerror处理error事件。该事件在读取操作发生错误时触发。
FileReader.onload处理load事件。该事件在读取操作完成时触发。
FileReader.onloadstart处理loadstart事件。该事件在读取操作开始时触发。
FileReader.onloadend处理loadend事件。该事件在读取操作结束时(要么成功,要么失败)触发。
FileReader.onprogress处理progress事件。该事件在读取Blob时触发。

2.3.5 方法

函数名说明参数返回值
FileReader.abort()中止读取操作。在返回时,readyState属性为DONE。
FileReader.readAsArrayBuffer()开始读取指定的 Blob中的内容, 一旦完成, result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象.result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据
FileReader.readAsBinaryString()开始读取指定的Blob中的内容。一旦完成,result属性中将包含所读取文件的原始二进制数据。
FileReader.readAsDataURL(blob)开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的Base64字符串以表示所读取文件的内容。Blob类型 或 File类型result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容
FileReader.readAsText(blob[, encoding])开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个字符串以表示所读取的文件内容。这个方法是异步的,也就是说,只有当执行完成后才能够查看到结果,如果直接查看是无结果的,并返回undefinedblob Blob类型 或 File类型;encoding传入一个字符串类型的编码类型,如缺省,则默认为“utf-8”类型

2.3.6 案例

  1. 预览选中的图片
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <input type="file" onchange="previewFile()">
    <img src="" alt="">
  </body>
  <script>
    function previewFile() {
      var preview = document.querySelector("img");
      var file = document.querySelector("input[type=file]").files[0];
      var reader = new FileReader();

      reader.addEventListener("load",
        function() {
          console.log(arguments)
          debugger
          preview.src = reader.result;
        },
        false
      );

      if (file) {
        reader.readAsDataURL(file);
      }
    }
  </script>
</html>
  1. 读取本地txt文件
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <input type="file" id='upload' />
</body>
<script>
  
document.getElementById('upload').addEventListener('change', function (e) {
    var file = this.files[0];
    const reader = new FileReader();
    reader.onload = function () {
        const result = reader.result;
        debugger
        console.log(result);
    }
    reader.readAsText(file);
}, false);

</script>
</html>
  1. Blob串转 ArrayBuffer、String、DataURL、ObjectURL
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body></body>
  <script>
    const jsonData = { name: "huangbiao", age: 32 };
    let jsonStr = JSON.stringify(jsonData);
    console.log(jsonStr);
    // 字符串 转为 Blob 对象
    let blob = new Blob([jsonStr], { type: "application/json" });
    console.log("blob.size", blob.size);

    function readBlob(blob, type) {
      return new Promise(function (resolve) {
        let reader = new FileReader();
        reader.onload = function (event) {
          console.log(event);
          resolve(event.target.result);
        };
        switch (type) {
          case "ArrayBuffer":
            // FileReader 将 Blob 转为 ArrayBuffer 对象(即Buffer对象)
            reader.readAsArrayBuffer(blob);
            break;
          case "DataURL":
            // FileReader 将 Blob 转为 Base64字符串
            reader.readAsDataURL(blob);
            break;
          case "Text":
            // FileReader 将 Blob 转为 文本,并且是以UTF8编码的形式
            reader.readAsText(blob, "utf-8");
            break;
          case "ObjectURL":
            // FileReader 将 Blob 转为 ObjectURL对象(一个路径指向文件)
            const objectURL = URL.createObjectURL(blob)
            resolve(objectURL);
            break;
          default:
            break;
        }
      });
    }

    readBlob(blob ,'ArrayBuffer').then(result => {
      console.log('ArrayBuffer',result);
    })
    readBlob(blob ,'DataURL').then(result => {
      console.log('DataURL',result);
    })
    readBlob(blob ,'Text').then(result => {
      console.log('Text',result);
    })
    readBlob(blob ,'ObjectURL').then(result => {
      console.log('ObjectURL',result);
    })
  </script>
</html>

2.4 File

2.4.1 概念

2.4.2 来源

2.4.3 构造函数 new File(bits, name[, options]);

var file = new File(["foo"], "foo.txt", {
  type: "text/plain",
});

2.4.4 属性

File 接口也继承了 Blob 接口的属性:

属性名是否只读说明
File.lastModified只读返回当前 File 对象所引用文件最后修改时间,自 UNIX 时间起始值(1970年1月1日 00:00:00 UTC)以来的毫秒数。
File.lastModifiedDate只读返回当前 File 对象所引用文件最后修改时间的 Date 对象。
File.name只读返回当前 File 对象所引用文件的名字。
File.size只读返回文件的大小。
File.webkitRelativePath只读返回 File 相关的 path 或 URL。
File.type只读返回文件的 多用途互联网邮件扩展类型(MIME Type)

2.5 DataURL

2.5.1 FileReader.readAsDataURL(blob);

包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。

2.5.1个人理解

就是base64的字符串编码,前面的“data:”格式固定

2.5.1数据案例

data:application/json;base64,eyJuYW1lIjoiaHVhbmdiaWFvIiwiYWdlIjozMn0=

2.5.1Base64

2.6 ObjectURL

2.6.1 URL.createObjectURL() 静态方法

2.6.1 URL

参考 URL MDN

2.6.2.1 概念

URL接口用于解析,构造,规范化和编码 URLs。
个人理解:按照规范方便解析URL地址,通过方法获取对应的属性(例如地址、端口、协议、参数等),而不是人为的去解析字符串

2.6.2.2 构造函数 new URL(url, [base])

url
是一个表示绝对或相对 URL 的 DOMString。如果url 是相对 URL,则会将 base 用作基准 URL。如果 url 是绝对URL,则将忽略 base,无论是否有给出。
base 可选
是一个表示基准 URL 的 DOMString,在 url 是相对 URL 时,它才会起效。如果未指定,则默认为 ‘’。

2.6.2.3 属性

属性说明
hash包含’#'的USVString,后跟URL的片段标识符。
host一个USVString,其中包含域(即主机名),后跟(如果指定了端口)“:”和URL的端口。
hostname包含 URL 域名的 USVString。
href包含完整 URL 的 USVString。
origin 只读返回一个包含协议名、域名和端口号的 USVString。
password包含在域名前面指定的密码的 USVString 。
pathname以 ‘/’ 起头紧跟着 URL 文件路径的 DOMString。
port包含 URL 端口号的 USVString。
protocol包含 URL 协议名的 USVString,末尾带 ‘:’。
search一个USVString ,指示URL的参数字符串; 如果提供了任何参数,则此字符串包括所有参数,并以开头的“?”开头 字符。
searchParams 只读URLSearchParams对象,可用于访问search中找到的各个查询参数。
username包含在域名前面指定的用户名的 USVString。

2.6.2.4 方法

方法名说明
toString()返回包含整个URL的USVString。 它是URL.href的同义词,尽管它不能用于修改值。
toJSON()返回包含整个URL的USVString。 它返回与href属性相同的字符串。

2.6.2.5 静态方法

方法名参数说明
URL.createObjectURL(object);用于创建 URL 的 File 对象、Blob 对象或者 MediaSource 对象。​返回一个DOMString ,包含一个唯一的blob链接(该链接协议为以blob:,后跟唯一标识浏览器中的对象的掩码)。
revokeObjectURL()销毁之前使用URL.createObjectURL()方法创建的URL实例。

createObjectURL 内存管理
在每次调用 createObjectURL() 方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放
浏览器在 document 卸载的时候,会自动释放它们,但是为了获得最佳性能和内存使用状况,你应该在安全的时机主动释放掉它们。

2.6.2.6 字符串转为Blob对象实现文件下载(因为Blob可以转为ObjectURL)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button onclick="download()">下载</button>
  </body>
  <script>
    // 利用 ObjectURL 路径来实现下载
    function download() {
      const jsonData = { name: "huangbiao", age: 32 };
      let jsonStr = JSON.stringify(jsonData);

      const blob = new Blob([jsonStr], {type: 'application/json'})
      const objectURL = URL.createObjectURL(blob)

      const a = document.createElement('a')
      a.download = 'hello.json'
      a.rel = 'noopener'
      a.href = objectURL
      // a.dispatchEvent(new MouseEvent('click'))
      a.click()
      URL.revokeObjectURL(objectURL)
    }
  </script>
</html>

三、Canvas 保存图片

3.1 canvas.toDataURL(‘image/png’)

默认设定。创建一个PNG图片。
Default setting. Creates a PNG image.

3.2 canvas.toDataURL(‘image/jpeg’, quality)

创建一个JPG图片。你可以有选择地提供从0到1的品质量,1表示最好品质,0基本不被辨析但有比较小的文件大小。

3.3 canvas.toBlob(callback, type, encoderOptions)

这个创建了一个在画布中的代表图片的Blob对像。

四、总结: 各种数据类型相互转换思路

  1. string ----> Blob -----> (ArrayBuffer 、DataURL、ObjectURL、Text) 因此可以实现文本的文件下载
  2. ObjectURL 可以实现 文件下载
  3. DataURL 实际上是 Base64 可以作为图片显示
  4. canvase 可以转为 DataURL / ObjectURL,因此可以实现下载
  5. file ----> Blob ----> Text因此可以实现读取本地文件,转为文本展示出来

标签:web,DataURL,string,URL,DataView,对象,Blob,new,blob
来源: https://blog.csdn.net/hbiao68/article/details/123094909