前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Blob、ArrayBuffer、File、FileReader和FormData的区别

Blob、ArrayBuffer、File、FileReader和FormData的区别

作者头像
码客说
发布2019-10-22 17:44:43
5K0
发布2019-10-22 17:44:43
举报
文章被收录于专栏:码客

前言

Blob、ArrayBuffer、File、FileReader、FormData这些名词总是经常看到,知道一点又好像不知道,像是同一个东西好像又不是,总是模模糊糊,最近终于下决心要弄清楚。

这些名词里:

  • Blob、ArrayBuffer、File可以归为一类,它们都是数据;
  • FileReader算是一种工具,用来读取数据;
  • FormData可以看做是一个应用数据的场景。

因此,我们首先着重区分Blob、ArrayBuffer、File,然后再对fileReader和FormData做简要介绍。

Blob

概念理解

  • Blob的全称是binary large object,表示二进制大对象,并不是前端的特有对象,而是计算机界的通用术语,MySql/Oracle数据库中,就有一种Blob类型,专门存放二进制数据。
  • MDN中官方的解释是:一个Blob对象就是一个包含有只读原始数据的类文件对象。通俗点,我们可以直接将Blob看做是一个不可修改的二进制文件。

简单来说,Blob就是一个只读的二进制文件,我们可以知道它的文件大小(size),文件类型(type),并可以对其作出分割(slice)。

使用

构造函数

直接通过new Blob()就可以创建一个Blob对象

代码语言:javascript
复制
var aBlob = new Blob( array, options );

array(可选):是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体。(暂时可以不用理解,就可以看作是一堆数据) options(可选):一个对象,用来设置Blob的一些属性。主要的是一个type属性,表示Blob的类型(其他暂时也不用管)。

简单来说,就是可以通过向new Blob()传一堆数据,生成一个Blob对象

属性

  • Blob.size(只读):Blob对象中包含的数据大小(字节)
  • Blob.type(只读):表明该Blob对象所包含数据的MIME类型。例如若为图片,此字段就类似为’image/jpeg‘。如果类型未知,则该值为空字符串。

方法

Blob只有一个slice方法,实现对文件的分割(注意这里并不违背Blob的只读性,slice只是只是复制指定范围内的Blob数据)。

代码语言:javascript
复制
Blob.slice(start, end ,contentType)

start:开始索引,可以为负数,语法类似于数组的slice方法。默认值为0。 end:结束索引,可以为负数,语法类似于数组的slice方法。默认值为最后一个索引。 contentType:新的Blob对象的MIME类型,这个值将会成为新的Blob对象的type属性的值,默认为一个空字符串。

Base64 => File

代码语言:javascript
复制
//将base64转换为blob
dataURLtoBlob: function (dataurl) {
  var arr = dataurl.split(','),
      mime = arr[0].match(/:(.*?);/)[1],
      bstr = atob(arr[1]),
      n = bstr.length,
      u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], {type: mime});
},
//将blob转换为file
blobToFile: function (theBlob, fileName) {
  theBlob.lastModifiedDate = new Date();
  theBlob.name = fileName;
  return theBlob;
},

Blob下载到本地

代码语言:javascript
复制
function saveShareContent (content, fileName) {
    let downLink = document.createElement('a')
    downLink.download = fileName
    //字符内容转换为blod地址
    let blob = new Blob([content])
    downLink.href = URL.createObjectURL(blob)
    // 链接插入到页面
    document.body.appendChild(downLink)
    downLink.click()
    // 移除下载链接
    document.body.removeChild(downLink)
}

content是需要下载的内容 fileName是保存的文件的名字

原理就是利用Blob对象把需要下载的内容转换为二进制,然后借助<a>标签的href属性和download属性,实现下载。

ArrayBuffer

ArrayBuffer的概念和用法相对比较复杂(它本身不复杂,只是使用方式比较丰富),之后会在另外一篇博客作出解释,这里仅做简要说明,主要是理解它的宏观概念。

  • ArrayBuffer就是一个二进制数据通用的固定长度容器。通俗点说,就是内存上一段连续的二进制数据。
  • 我们可以对ArrayBuffer进行读写,但需要借助它提供的工具TypeArray或DataView

Blob与ArrayBuffer的关系

  • 相同点: Blob和ArrayBuffer都是二进制的容器;
  • ArrayBuffer:ArrayBuffer更底层,就是一段纯粹的内存上的二进制数据,我们可以对其任何一个字节进行单独的修改,也可以根据我们的需要以我们指定的形式读取指定范围的数据
  • Blob:Blob就是将一段二进制数据做了一个封装,我们拿到的就是一个整体,可以看到它的整体属性大小、类型;可以对其分割,但不能了解到它的细节
  • 联系:Blob可以接受一个ArrayBuffer作为参数生成一个Blob对象,此行为就相当于对ArrayBuffer数据做一个封装,之后就是以整体的形式展现了
  • 应用上的区别:由于ArrayBuffer和Blob的特性,Blob作为一个整体文件,适合用于传输;而只有需要关注细节(比如要修改某一段数据时),才需要用到ArrayBuffer

Buffer

但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。

在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。Buffer 库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer 库。原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。

在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例,但是Buffer对内存的权限操作相比很大,可以直接捕获一些敏感信息,所以在v6.0以后,官方文档里面建议使用 Buffer.from() 接口去创建Buffer对象。

Buffer 与字符编码

Buffer 实例一般用于表示编码字符的序列,比如 UTF-8 、 UCS2 、 Base64 、或十六进制编码的数据。 通过使用显式的字符编码,就可以在 Buffer 实例与普通的 JavaScript 字符串之间进行相互转换。

代码语言:javascript
复制
const buf = Buffer.from('runoob', 'ascii');

// 输出 72756e6f6f62
console.log(buf.toString('hex'));

// 输出 cnVub29i
console.log(buf.toString('base64'));

Node.js 目前支持的字符编码包括:

  • ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。
  • utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。
  • utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。
  • ucs2 - utf16le 的别名。
  • base64 - Base64 编码。
  • latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。
  • binary - latin1 的别名。
  • hex - 将每个字节编码为两个十六进制字符。

创建 Buffer 类

Buffer 提供了以下 API 来创建 Buffer 类:

  • Buffer.alloc(size[, fill[, encoding]]): 返回一个指定大小的 Buffer 实例,如果没有设置 fill,则默认填满 0
  • Buffer.allocUnsafe(size): 返回一个指定大小的 Buffer 实例,但是它不会被初始化,所以它可能包含敏感的数据
  • Buffer.allocUnsafeSlow(size)
  • Buffer.from(array): 返回一个被 array 的值初始化的新的 Buffer 实例(传入的 array 的元素只能是数字,不然就会自动被 0 覆盖)
  • Buffer.from(arrayBuffer[, byteOffset[, length]]): 返回一个新建的与给定的 ArrayBuffer 共享同一内存的 Buffer。
  • Buffer.from(buffer): 复制传入的 Buffer 实例的数据,并返回一个新的 Buffer 实例
  • Buffer.from(string[, encoding]): 返回一个被 string 的值初始化的新的 Buffer 实例
代码语言:javascript
复制
// 创建一个长度为 10、且用 0 填充的 Buffer。
const buf1 = Buffer.alloc(10);

// 创建一个长度为 10、且用 0x1 填充的 Buffer。 
const buf2 = Buffer.alloc(10, 1);

// 创建一个长度为 10、且未初始化的 Buffer。
// 这个方法比调用 Buffer.alloc() 更快,
// 但返回的 Buffer 实例可能包含旧数据,
// 因此需要使用 fill() 或 write() 重写。
const buf3 = Buffer.allocUnsafe(10);

// 创建一个包含 [0x1, 0x2, 0x3] 的 Buffer。
const buf4 = Buffer.from([1, 2, 3]);

// 创建一个包含 UTF-8 字节 [0x74, 0xc3, 0xa9, 0x73, 0x74] 的 Buffer。
const buf5 = Buffer.from('tést');

// 创建一个包含 Latin-1 字节 [0x74, 0xe9, 0x73, 0x74] 的 Buffer。
const buf6 = Buffer.from('tést', 'latin1');

写入缓冲区

语法

写入 Node 缓冲区的语法如下所示:

代码语言:javascript
复制
buf.write(string[, offset[, length]][, encoding])
参数

参数描述如下:

  • string - 写入缓冲区的字符串。
  • offset - 缓冲区开始写入的索引值,默认为 0 。
  • length - 写入的字节数,默认为 buffer.length
  • encoding - 使用的编码。默认为 ‘utf8’ 。

根据 encoding 的字符编码写入 string 到 buf 中的 offset 位置。 length 参数是写入的字节数。 如果 buf 没有足够的空间保存整个字符串,则只会写入 string 的一部分。 只部分解码的字符不会被写入。

返回值

返回实际写入的大小。如果 buffer 空间不足, 则只会写入部分字符串。

实例
代码语言:javascript
复制
buf = Buffer.alloc(256);
len = buf.write("www.psvmc.cn");

console.log("写入字节数 : "+  len);

执行以上代码,输出结果为:

代码语言:javascript
复制
$node main.js
写入字节数 : 14

Blob => Buffer

代码语言:javascript
复制
let reader = new FileReader();
reader.onload = function () {
  let buffer = Buffer.from(reader.result);
};
reader.readAsArrayBuffer(blob);

File

概念理解

  • file根据名字很容易理解,就是纯粹的文件。通常,表示我们使用<input type="file">选择的FileList对象,或者是使用拖拽操作搞出的DataTransfer对象。
  • file对象也是二进制对象,从属于Blob;也就是说file是Blob里的一个小类,Blob的属性和方法都可以用于file,而file自己也有自己特有的属性和方法。对于Blob和file都有的属性,推荐使用Blob的属性

File就是Blob里面的一个小类,继承Blob的方法和属性,拥有自己特有的属性。通常表示<input type="file">里的fileList对象

使用

这里就不做过多介绍了,可以直接参考MDN上的介绍

Blob => File

代码语言:javascript
复制
//将blob转换为file
blobToFile: function (theBlob, fileName) {
  theBlob.lastModifiedDate = new Date();
  theBlob.name = fileName;
  return theBlob;
}

FileReader

  • 前面提到Blob对象时一个只读对象,但它是一个二进制对象,如果直接读取就只能拿到一堆01数据,因此需要借助专门的工具来读取,这个工具就是fileReader。
  • 通过fileReader可以将Blob读取为不同的格式,具体将在另一篇博文中讲到。 Q:前面提到,ArrayBuffer也需要借助工具(以dataView为例)读取数据,那和fileReader有什么区别呢? A:我理解的,ArrayBuffer的工具dataView只是简单的读取数据,最多就是讲数据转为数字或字符串;但fileReader可以看做是多了一道编码的过程,通过FileReader.readAsDataURL(blob)就是将二进制数据读取并编码为Base64格式,FileReader.readAsText(blob)就是将二进制数据读取并编码为字符串形式。

利用FileReader结合Node.js保存Blob为本地文件

代码语言:javascript
复制
saveMedia = (blob) => {
  let reader = new FileReader();
  let filename = this.mediaOutputPath + "/" + this.getnowstr() + "_vedio.webm";
  reader.onload = function () {
    let buffer = Buffer.from(reader.result);
    const fs = require('fs')
    fs.writeFile(filename, buffer, {}, (err, res) => {
      if (err) {
        console.error(err);
        return
      }
    })
  };
  reader.readAsArrayBuffer(blob);
};

FormData

准确来说,FormData其实与上述内容关系就不大了。它是XMLHttpRequest Level 2添加的一个新的接口,我们可以通过JavaScript用一些键值对来模拟一系列表单控件。FormData的最大优点就是,比起普通的ajax, 使用FormData我们可以异步上传一个二进制文件,而这个二进制文件,就是我们上面讲的Blob对象。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-09-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • Blob
    • 概念理解
      • 使用
        • Base64 => File
          • Blob下载到本地
          • ArrayBuffer
          • Buffer
            • Buffer 与字符编码
              • 创建 Buffer 类
                • 写入缓冲区
                  • 语法
                  • 参数
                  • 返回值
                  • 实例
                • Blob => Buffer
                • File
                  • 概念理解
                    • 使用
                      • Blob => File
                      • FileReader
                      • FormData
                      相关产品与服务
                      容器服务
                      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档