JavaScript 困惑之 ArrayBuffer

  在就版本的 JavaScrip中, 是没有读写二进制数据能力的,但随着 es5 中 Blob 对象的引入以及 es6 中 ArrayBuffer 对象、TypedArray 和 DataView 对象的规范化, JS 处理二进制数据的能力大幅度增强,也能直接处理文件流,网络流等二进制 Buffer 数据了。

image

1、Blob对象

  Blob(Binary Large Object)表示二进制类型的大对象。在数据库管理系统中,将二进制数据存储为一个单一个体的集合。Blob 通常是影像、声音或多媒体文件。在 JavaScript 中 Blob 类型的对象表示不可变的类似文件对象的原始数据 为了更直观的感受 Blob 对象,我们先来使用 Blob 构造函数,创建一个 aBlob 对象:

var aBlob = new Blob(blobParts, options);
  1. blobParts:它是一个由 ArrayBuffer,ArrayBufferView,Blob,DOMString 等对象构成的数组。DOMStrings 会被编码为 UTF-8。
  2. options:一个可选的对象,包含以下两个属性:

           type —— 默认值为 "",它代表了将会被放入到 blob 中的数组内容的 MIME 类型。

           endings —— 默认值为 "transparent",用于指定包含行结束符 \n 的字符串如何被写入。它是以下两个值中的一个:"native",代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 "transparent",代表会保持 blob 中保存的结束符不变。

blob对象的主要属性方法:

属性:

  1. size(只读):表示 Blob 对象中所包含数据的大小(以字节为单位)。
  2. type(只读):一个字符串,表明该 Blob 对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串。

方法:

  1. slice([start[, end[, contentType]]]):返回一个新的 Blob 对象,包含了源 Blob 对象中指定范围内的数据。
  2. stream():返回一个能读取 blob 内容的 ReadableStream
  3. text():返回一个 Promise 对象且包含 blob 所有内容的 UTF-8 格式的 USVString
  4. arrayBuffer():返回一个 Promise 对象且包含 blob 所有内容的二进制格式的 ArrayBuffer

Blob 对象是不可改变的。我们不能直接在一个 Blob 中更改数据,但是我们可以对一个 Blob 进行分割,从其中创建新的 Blob 对象,将它们混合到一个新的 Blob 中。这种行为类似于 JavaScript 字符串:我们无法更改字符串中的字符,但可以创建新的更正后的字符串。

2、File对象

  File 对象代表一个文件,用来读写文件信息。它继承了 Blob 对象,或者说是一种特殊的 Blob 对象,所有可以使用 Blob 对象的场合都可以使用它。

我们接触的多数关于 File 的操作都是读取,js也为我们提供了手动创建 File 对象的构造函数:File(bits, name[, options])。

var myFile = new File([], 'file.bin', {
   lastModified: new Date(2018, 1, 1),
});
myFile.lastModified // 1517414400000
myFile.name // "file.bin"
myFile.size // 0
myFile.type //
  • bits (required) ArrayBuffer,ArrayBufferView,Blob,或者 Array[string] —或者任何这些对象的组合。这是 UTF-8 编码的文件内容。。
  • name [String] (required) 文件名称,或者文件路径.
  • options [Object] (optional) 选项对象,包含文件的可选属性。可用的选项如下:
  • type: string, 表示将要放到文件中的内容的MIME类型。默认值为 ‘’ 。
  • lastModified: 数值,表示文件最后修改时间的 Unix 时间戳(毫秒)。默认值为 Date.now()。

3、FileList 对象

  FileList对象是一个类似数组的对象,代表一组选中的文件,每个成员都是一个 File 实例。它主要出现在两个场合。文件控件节点()的files属性,返回一个 FileList 实例。

拖拉一组文件时,目标区的DataTransfer.files属性,返回一个 FileList 实例。

var files = document.getElementById('fileItem').files;

files instanceof FileList // true

3、FileReader 对象

FileReader 有以下的实例属性。

  • FileReader.error:读取文件时产生的错误对象
  • FileReader.readyState:整数,表示读取文件时的当前状态。一共有三种可能的状态,0表示尚未加载任何数据,1表示数据正在加载,2表示加载完成。
  • FileReader.result:读取完成后的文件内容,有可能是字符串,也可能是一个 ArrayBuffer 实例。
  • FileReader.onabort:abort事件(用户终止读取操作)的监听函数。
  • FileReader.onerror:error事件(读取错误)的监听函数。
  • FileReader.onload:load事件(读取操作完成)的监听函数,通常在这个函数里面使用result属性,拿到文件内容。
  • FileReader.onloadstart:loadstart事件(读取操作开始)的监听函数。
  • FileReader.onloadend:loadend事件(读取操作结束)的监听函数。
  • FileReader.onprogress:progress事件(读取操作进行中)的监听函数。

其主要方法如下

  • abort():void    终止文件读取操作
  • readAsArrayBuffer(file):void    异步按字节读取文件内容,结果用ArrayBuffer对象表示
  • readAsBinaryString(file):void    异步按字节读取文件内容,结果为文件的二进制串
  • readAsDataURL(file):void    异步读取文件内容,结果用data:url的字符串形式表示
  • readAsText(file,encoding):void    异步按字符读取文件内容,结果用字符串形式表示

其中readAsArrayBuffer可以将文件转换为arraybuffer\text\data等

function onChange(event) {
   var file = event.target.files[0];
   var reader = new FileReader();
   reader.onload = function (event) {
     console.log(event.target.result)
   };

  reader.readAsText(file);
}

4、ArrayBuffer对象

  代表内存之中的一段二进制数据,可以用数组的方法操作内存,ArrayBuffer 是视图或TypeArray的底层缓冲区,不能直接操作ArrayBuffer,需要通过视图或TypeArray来操作它

ArrayBuffer()是一个普通的JavaScript构造函数,可用于在内存中分配特定数量的字节空间。

const buf = new ArrayBuffer(16); // 在内存中分配16 字节

alert(buf.byteLength);

5、TypedArray视图对象

我们无法对ArrayBuffer 进行直接操作,需要通过TypedArray进行操作

共包括 9 种类型的视图,比如Uint8Array(无符号 8 位整数)数组视图, Int16Array(16 位整数)数组视图, Float32Array(32 位浮点数)数组视图等等。

  • Int8Array:8位有符号整数,长度1个字节。
  • Uint8Array:8位无符号整数,长度1个字节。
  • Uint8ClampedArray:8位无符号整数,长度1个字节,溢出处理不同。
  • Int16Array:16位有符号整数,长度2个字。
  • Uint16Array:16位无符号整数,长度2个字节。
  • Int32Array:32位有符号整数,长度4个字节。
  • Uint32Array:32位无符号整数,长度4个字节。
  • Float32Array:32位浮点数,长度4个字节。
  • Float64Array:64位浮点数,长度8个字节。
let buf = new ArrayBuffer(32)
let int32 = new Int32Array(buf)
let uint8 = new Uint8Array(buf)
console.log(int32[0]) // 0
console.log(uint8[0]) // 0

// 还可以直接修改

int32[0] = 1
console.log(int32[0]) // 1
console.log(uint8[0]) // 1

6、DataView 对象:

  TypedArray只能放置一种数据类型,对于要存放不同的 数据类型,则需要DataView,不同于类型化数组,一个数组只能存放同一类型的数据,DataView 可以在内存中存放不同类型的数据。

posted @ 2022-10-18 16:41  Min.Xiaoshuang  阅读(1198)  评论(0编辑  收藏  举报