惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
U
Unit 42
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Martin Fowler
Martin Fowler
L
LangChain Blog
博客园_首页
博客园 - 【当耐特】
Vercel News
Vercel News
I
InfoQ
GbyAI
GbyAI
爱范儿
爱范儿
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
B
Blog RSS Feed
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
G
Google Developers Blog
大猫的无限游戏
大猫的无限游戏
Apple Machine Learning Research
Apple Machine Learning Research
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Proofpoint News Feed
美团技术团队
V
V2EX
Stack Overflow Blog
Stack Overflow Blog
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Help Net Security
Recent Announcements
Recent Announcements
Microsoft Azure Blog
Microsoft Azure Blog
D
Docker
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
小众软件
小众软件
J
Java Code Geeks
S
SegmentFault 最新的问题
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
MongoDB | Blog
MongoDB | Blog
The Cloudflare Blog
Recorded Future
Recorded Future
阮一峰的网络日志
阮一峰的网络日志
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog
Microsoft Security Blog
Microsoft Security Blog

博客园 - Albert_MIN

在 ASP.NET Core MVC 中,接收数据的几种方式 Content-Type 对应不同的前端数据结构与构造方式 Revit二次开发 钢筋生成API(二) Revit二次开发 钢筋生成API(一) revit二次开发 钢筋布置方式 revit二次开发之 钢筋功能详细分析 revit 二次开发之收集器、过滤器和选择器 Revit Server的注意要配置说明 WCF文件配置服务 WCF服务的各种绑定 Revit二次开发之 对象的隐藏与显示 Revit二次开发之 GeometryObject分析 Revit二次开发之 Material 分析 Revit二次开发之 PolymeshTopology Revit 二次开发之 图纸的导出 Revit开发之 IExportContext接口详细 JS 困惑之this的指向 Revit二次开发之 族的创建 Revit二次开发 钢筋生成 Revit二次开发之 尺寸标线(二) Revit二次开发之 尺寸标线
JavaScript 困惑之 ArrayBuffer
Albert_MIN · 2022-10-18 · via 博客园 - Albert_MIN

  在就版本的 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 可以在内存中存放不同类型的数据。