JavaScript二进制数据处理

JavaScript类型化数组

使用JavaScript类型化数组可以方便地操作二进制数据,它分为两层,数据缓存和数据视图,数据缓存(ArrayBuffer)用于储存数据,但不负责数据读写,读写数据需要创建数据视图来实现 ,类型化数组就是数据视图的一种。

数据缓存和数据视图的关系如下:

let buffer = new ArrayBuffer(16)
buffer.length // 16
let int32View = new Int32Array(buffer)
int32View.length // 4
let int16View = new Int16Array(buffer)
int16View.length // 8

很多操作二进制数据的API用到了类型化数组

  • 文件操作:FileReader.prototype.readAsArrayBuffer()
  • AJAX: XMLHttpRequest.prototype.send()
  • 图像操作: ImageData.data

File和Blob

File和Blob提供了文件操作的接口,文件也可以看作是一块(尚未加载的)二进制数据,需要读出来,因此其操作大多是异步的。File和Blob的区别在于后者提供了文件基本操作,前者在此基础上增加文件的常用属性,如name、lastModified。
读文件内容有通用方法是创建一个FileReader对象,它提供了将文件读取为ArrayBuffer,dataURL、文本或者Binary String的API
比较简单的应用可以使用Blob.arrayBuffer()的内置方法读取二进制数据,它返回一个Promise,不提供读取进度的反馈信息。UTF8编码的文本文件可以使用Blob.text()读取其内容,如果文本文件不是UTF8编码,则需要使用FileReader。
URL.createObjectURL()可以将文件内容转化为dataURL,这是同步操作,不适用于大文件或者网络带宽较小的场景。

String

String类型不适合处理二进制数据,因为String是文本的抽象,即Unicode字符集上元素的集合。文本和适合持久存储的二进制数据之间存在编码过程,所有文本都可以通过编码转化成二进制数据,但反过来不成立,即对于任一编码,都存在无法解码成文本的二进制数据,因此String类型不适合处理二进制数据。

虽然任何文本编码都不是String和二进制数据之间的双向映射,但可以创建一个这样的映射,历为JavaScript String是用UTF16字符实现的,每个字符理论上可以表示0-65535之间的任意值,而二进制数据的每个字节都可以用0-255之间的任意数来表示,因此String的每个字符和二进制数据每个字节之间的可以建立联系: s.charCodeAt(i) === new Uint8Array(buffer)[i], 这就是Binary String, 一种与文本无关,专为处理二进制数据而存在的数据类型。

Binary String用了16位来表示8位有效信息,虽然浪费了一倍的空间,但避免了不少问题,例如字节序,二进制数据字节长度为单数,UTF-16代理对

Base64

Base64是一种用ASCII字符表示二进制数据的编码格式,共使用了64个可打印的ASCII字符,每个字符可表示6位有效信息,每3个字节的数据被编码成4个ASCII字符,数据大小增加了约1/3。

JavaScript提供了btoa()将Binary String编码为base64,以及atob()将base64解码为Binary String。如果文本只包含ASCII字符,也可以直接把它交给btoa()来编码,因为这种String数据和Binary String恰好是相同的。超出这个范围,天然的一对一关系就不存在了,必须把文本先编码成二进制数据,再将二进制数据编码成base64,这种情况下要确保编码方和解码方使用的字符编码相同,UTF16(效率高)或UTF8(通用)是常见的选择,MDN提出将String编码成base64的多种方案,都是基于UTF16或者UTF8(使用encodeURIComponent()的例子可以认为是基于UTF8)。

dataURI

JavaScript提供了encodeURI()和encodeURIComponent()两个函数将String编码成UTF8,但将大部分字节(UTF8每个字符可能用1、2、3、4个字节来表示)进行了转义。这两个函数的区别是,前者不会对URI里的保留字符如/、:、@、?、&、#进行转义,其输出可以直接作为URI使用,后者会对URI里的特殊字符进行转译,其输出可以嵌入到URI的内容里。

这两个函数可以对所有有效的文本进行编码(如果String数据中存在不完整的UTF16代理对,会抛出异常:URIError: malformed URI sequence),对于二进制数据,可以先将其转化为base64再编码成URI,因此所有数据都可以用URI来表示,其标准化的描述就是dataURI(RFC 2397)。

dataURL的格式如下:

data:[<mediatype>][;base64],<data>

mediatype包括数据的MIME类型和字符编码等其它信息,base64表示使用了base64编码,data部分是经过URI转义的数据。尽管创建一个dataURL不难(前面已经叙述),读取dataURL则可能遇到很多复杂的情况(mediatype)。

mediatype  := [ type "/" subtype ] *( ";" parameter )
parameter  := attribute "=" value

参考:JavaScript二进制数据处理

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值