前端文件操作基础知识(一)文件对象篇

2019-05-14 00:00:00

文件操作相关对象 由于篇幅有点长,所以先把总结写在前面。

  • Blob/ File对象结合 FileReader可转换为文本、二进制数据、ArrayBuffer
  • Blob/ File主要用于上传和导出
  • ArrayBuffer主要用于修改底层二进制数据

前言

导入导出功能已经是非常普遍了,由于在开发该功能的过程中,发现与其关联的知识还不少,即便完成功能开发也仍旧对很多东西一知半解,又担心往后突然Bug甩过来一脸懵逼手足无措,所以索性抽了个时间将各部分了解并整理一遍。

本文主要探讨 Blob以及与 Blob相关的二进制数据对象的使用方法。

Blob对象

Blob对象是一个二进制数据容器

Blob对象来源于:

  • canvas.toBlob()
  • 接口请求:ajax 设置 responseType: blob 或者 fetch 的 response.blob()
ajax:
    let xhr = new XMLHttpRequest()
    xhr.open('GET', someUrl)
    xhr.responseType = 'blob'
    
fetch:
    fetch(someUrl)
      .then(response => {
        return response.blob();
      })
      .then(myBlob => {
        console.log(myBlob);
      });
  • new Blob(blobParts[, options])
blobParts: 数组,所有数据放进数组,可以为 ArrayBuffer、ArrayBufferView、Blob、DOMString(实际就是字符串,将被utf-8编码)

options:对象,通常不设置或设置 type。如:{type: 'text/plain'}代表 blob数据MIME类型为 text/plain

方法:

  • slice(start[, end[, contentType]])

用法与数组 slice相似,返回一个新的 Blob对象

应用:

  • 文件下载导出/图片资源/视频源路径隐藏:URL.createObjectURL(blob) + a标签/ img标签/ video标签
let str = ''.padEnd(1999, 'a')
let blob = new Blob([str])
let start = 0
let size = 300

while(start < blob.size) {
    let partBlob = blob.slice(start, start + size)
    let formdata = new FormData()
    formdata.append('data', partBlob)
    ... // 此处通过 ajax上传给后端
    start += size
}

File对象

File对象继承与 Blob对象,主要来源于:

  • < input type='file'> 选择元素后的 fileList对象
  • 拖拽生成的 DataTransfer对象

应用:

  • 图片预览
  • 文件分片上传

ArrayBuffer

ArrayBuffer 也是一个二进制容器,用于表示一段连续的内存。

那么为什么要同时存在 Blob和 ArrayBuffer两种二进制容器呢?其实它们两者设计目的是不一样的。ArrayBuffer设计的目的为了直接对数据进行处理,而 Blob不能修改二进制数据。有了 ArrayBuffer, 前端也就能操作二进制数据了。

主要来源于:

  • 构造函数:new ArrayBuffer()
  • ajax 设置 responseType: 'arraybuffer' 或者 fetch 的 response.arrayBuffer()
ajax:
    let xhr = new XMLHttpRequest()
    xhr.open('GET', someUrl)
    xhr.responseType = 'arraybuffer'
    
fetch:
    fetch(someUrl)
      .then(response => {
        return response.arrayBuffer();
      })
      .then(myBlob => {
        console.log(myBlob);
      })
  • canvas的 getImageData获取 TypedArray数组
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')

const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
const uint8ClampedArray = imageData.data    // 这里获取 TypedArray数组,之后便可以直接修改二进制数据
  • websocket通过 ArrayBuffer收发二进制数据

FileReader

FileReader提供一系列方法读取 Blob对象或 File对象。

  • readAsText

将 blob对象或 file对象转为文本

let reader = new FileReader()
reader.onload = function () {
    let text = reader.result    // 转化后的文本
}
reader.readAsText(blob) // 第二个参数为编码格式,默认为 utf-8
  • readAsDataURL

将 blob对象或 file对象转为 base64

let reader = new FileReader()
reader.onload = function () {
    let dataUrl = reader.result // 转化后的 base64
}
reader.readAsDataURL(blob)
  • readAsArrayBuffer

将 blob对象或 file对象转为 ArrayBuffer

/**
 * new Blob()的参数可以为 ArrayBuffer
 * readAsArrayBuffer又可以将 blob转为 ArrayBuffer
 * 所以,Blob和 ArrayBuffer可以互相转换
 */

let reader = new FileReader()
reader.onload = function () {
    let ab = reader.result // 转化后的 ArrayBuffer
}
reader.readAsArrayBuffer(blob)

Gitalking ...

Markdown is supported

Be the first guy leaving a comment!