Blob

在项目中涉及到要对html原生的audio组件进行样式复写,因此需要重新实现audio的一些功能,比如下载。实现一个下载大致的思路是服务端返回一段音频的二进制数据,客户端将其存放在Blob中,再通过URL.createObjectURL将其转换成blob url,最后动态创建a标签,添加download属性,模拟点击事件来实现下载。代码比较简单,我们重点来看看Blob是何方神圣。

const saveExcelFile = (blob, filename) => {
if (window.navigator.msSaveOrOpenBlob) {
// iE下使用msSaveBlob进行导出
navigator.msSaveBlob(blob, filename)
} else {
var href = window.URL.createObjectURL(blob) var save_link = document.createElementNS(
'http://www.w3.org/1999/xhtml',
'a'
)
save_link.href = href
save_link.download = filename // 解决火狐兼容问题
document.body.appendChild(save_link) var event = document.createEvent('MouseEvents')
event.initMouseEvent(
'click',
true,
false,
window,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null
)
save_link.dispatchEvent(event) document.body.removeChild(save_link)
// 释放blob url,可被GC回收
window.URL.revokeObjectURL(href)
}
}

根据MDN的介绍,我们可以知道Blob类型的对象是类似文件对象的二进制数据,它是immutable的,即数据不可变。而HTML5的File对象继承于Blob对象,并在其基础上做了些扩展,从而具备了在操作系统上操作文件的能力。我们可以利用Blob去做一些下载文件、分片上传等功能。熟悉ES6的小伙伴应该知道,ES6中有一个ArrayBuffer对象,也是用来存储二进制数据的,那它和Blob有什么区别呢?

ArrayBuffer

根据一些资料,ArrayBuffer设计的目的与WebGL项目有关,为了满足JS与显卡或声卡等操作系统原生接口大量的、实时的数据交换。传统的文本格式是传递一个32位的整数,这导致JS与原生接口需要频繁的转换数据格式,效率较低,因此设计了ArrayBuffer用于存储、操作二进制数据。

ArrayBuffer并不是真正的Array,而是个类数组对象。我们通过new ArrayBuffer(length)创建的ArrayBuffer的实例,仅仅代表开辟了一段连续的内存空间,length代表内存所占的字节大小。若需要对内存中的字节进行操作,则需要创建“视图”。视图分为两种:TypedArray和DataView,用于以指定的格式来读写二进制的数据。它们的区别在于:

  • TypedArray以指定的格式读写内存,例如:const v1 = new Int32Array(buffer)就是以32位有符号整型来创建视图,此时通过v1[0]去读或是去写都是以该格式进行的
  • 若是想以不同数据格式去读取内存的话,需要使用DataView。当我们执行const dv = new DataView(buffer)后,可以通过类似dv.getUint8(0)这样的方式,以8位无符号整型读取第一个字节;或是以dv.setInt32(1, 25)这种方式,在第二个字节写入值为25的32位有符号整型数据

注意:对于同一段内存创建的视图都是共享该内存的,在一个视图上进行的操作会影响另一个视图的读写。具体的可参考阮老师的教程

区别

  • ArrayBuffer可以对字节进行读写,而Blob是immutable的
  • ArrayBuffer存储在内存当中,Blob可以存储在磁盘或者内存中。例如文件,我们平时是存在磁盘中的。而像我们上面下载的例子中,我们的blob是在内存中的,因此在createObjectURL之后需要手动调用revokeObjectURL解除对内存的引用,使得blob可以被GC回收,释放内存。
  • ArrayBuffer可以通过“视图”来进行读写,而Blob可以通过FileReader去读,但是不能写
  • Blob和ArrayBuffer可以互相转换。Blob转ArrayBuffer可以通过:
    const reader = new FileReader()
    reader.onload = function() {
    console.log(reader.result)
    }
    reader.readAsArrayBuffer(blob)

    ArrayBuffer转Blob可以通过:

    const blob = new Blob([ArrayBuffer])

因此,当我们需要对字节进行操作的时候,我们应该选用ArrayBuffer,否则,我们用Blob会更加容易。

认识Js中的二进制数据的更多相关文章

  1. Js中各类型数据到bool的转换

    在返回Json字符串给前台时遇到的问题,返回的bool数据总是为TRUE 特意查了一下,发现了Js中各类数据转换到bool型是的结果. 希望能给遇到同样问题的人一点帮助.  数据类型  转换为bool ...

  2. 解决js中post提交数据并且跳转到指定页面的问题总结

    今天在开发中过程中遇到了这个问题,js中利用JQuery中的 $.post("url", id, function(){}); 这个方法是数据提交正常,但是后台处理完成之后跳转无法 ...

  3. js中如何将数据获得2位小数以及对数据进行千分位划分

    js中toFixed(n) 方法可把 数字四舍五入为指定小数位数n的数字,注意:这个方法只能对数据类型为Number的数据起作用,包括float,int等.例如:   123.12345.toFixe ...

  4. JS中浏览器的数据存储机制

    一.JS中的三种数据存储方式 cookie.sessionStorage.localStorage 二.cookie 1.cookie的定义: cookie是存储在浏览器上的一小段数据,用来记录某些当 ...

  5. JS中关于引用类型数据及函数的参数传递

    (JavaScript 中,函数的参数传递方式都是按值传递,没有按引用传递的参数) 一.数据类型 在 javascript 中数据类型可以分为两类: 基本类型值 primitive type,比如Un ...

  6. JSBinding+Bridge:逻辑代码中操作二进制数据

    以这2个函数为例 class File { public static byte[] ReadAllBytes(string path); public static void WriteAllByt ...

  7. js中Math()函数&&数据类型转换

    Math()函数: x的y次方:Math.pow(x,y) 取小数点后两位:num.toFixed(2) 数据类型转换: 字符串转换为数字:parseInt(num)转换为整数:parseFloat( ...

  8. python struct.pack() 二进制文件,文件中打包二进制数据的存储与解析

    学习Python的过程中,遇到一个问题,在<Python学习手册>(也就是<learning python>)中,元组.文件及其他章节里,关于处理二进制文件里,有这么一段代码的 ...

  9. js 中 前端过滤数据到后端的方法

    第一种方法: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF- ...

随机推荐

  1. MicroSoft CryptoAPI data/file encrypt/decrypt

    linux 用第三方库 Crypto++, 还未实战. CryptoAPI使用两种密钥:会话密钥与公共/私人密钥对.会话密钥使用相同的加密和解密密钥,这种算法较快,但必须保证密钥的安全传递.公共/私人 ...

  2. php位运算

    php位运算 /** * 位运算 */ echo "<pre>"; $aa = $a&$b; //按位与,相同位都为1时为1,其他都为0; echo " ...

  3. Tensor类型

    Tensor类型 1.Tensor有不同的数据类型,每种类型又有CPU和GPU两种版本: 2.默认的tensor类型是FloatTensor,t.set_default_tensor_type可以修改 ...

  4. ProgressBar三种style

    一.普通的ProgressBar显示如图 <ProgressBar        android:id="@+id/pbNormal"        android:layo ...

  5. Android中ListView的简单使用

    动态添加单行列表: 首先前提是你的布局文件里有一个ListView 单行列表的添加只需要一个list集合即可,使用ArrayAdapter数组适配器绑定更新就行了 首先声明一个ArrayAdapter ...

  6. linux系统做raid

    raid 常用步骤 1.ctrl+R 进入raid设置界面 2.F2 相当于右键功能 3.箭头 → 是下一个选项功能 4.ctrl+n是下一页,ctrl+p是前一页 5.Esc退出.最后ctrl+al ...

  7. 一、开水白菜(steamed Chinese cabbage in supreme soup)

    菜品历史 相传,开水白菜是由颇受慈禧赏识的川菜名厨黄敬临在清宫御膳房创制的. 黄敬临当厨时,不少人贬损川菜"只会麻辣,粗俗土气",为了破谣立证,他冥思苦想多时并经由百番尝试,终于开 ...

  8. 性能测试学习 第八课--LR12中针对WebServices协议的三种脚本开发模式

    一,webservices协议简介 webservices是建立可交互操作的分布式应用程序的新平台,它通过一系列的标准和协议来保证程序之间的动态连接, 其中最基本的协议包括soap,wsdl,uddi ...

  9. 值得收藏!!javascript数组中多条对象去重方式,很实用!!!

    在数组中都是数字的时候很好去重,例如:var  arr=[1,2,2,2,3,4,5,4,5,3,6]:可以用两层for循环或者其他方式进行去重 我在这里也给出一个方法吧: Array.prototy ...

  10. JS数组slice()和splice()的区别

    以前还是纯小白的时候,总会搞混JS数组的 slice() 和 splice() 方法.因为这2个方法名字太像了,就差一个字母,语法也有类似之处.    现在久了没用,有时候也会忘记,所以做一个总结来区 ...