前端文件的分片和组合

一、背景介绍

现在大文件上传或下载时,大概率要使用分片上传或下载,来达到断点续传的效果。不然一旦网络中断,之前已经上传或下载的一部分就丢失了,需要全部重新上传或下载。

二、分片

分片的操作js已经提供了一个现成的API
Blob.slice:用于创建一个包含源 Blob的指定字节范围内的数据的新 Blob 对象。
语法:

const blob = instanceOfBlob.slice(start , end , contentType)

start:可选
这个参数代表 Blob 里的下标,表示第一个会被会被拷贝进新的 Blob 的字节的起始位置。如果你传入的是一个负数,那么这个偏移量将会从数据的末尾从后到前开始计算。举例来说,-10 将会是 Blob 的倒数第十个字节。它的默认值是 0,如果你传入的 start 的长度大于源 Blob 的长度,那么返回的将会是一个长度为 0 并且不包含任何数据的一个 Blob 对象。
end:可选
这个参数代表的是 Blob 的一个下标,这个下标 -1 的对应的字节将会是被拷贝进新的Blob 的最后一个字节。如果你传入了一个负数,那么这个偏移量将会从数据的末尾从后到前开始计算。举例来说, -10 将会是 Blob 的倒数第十个字节。它的默认值就是它的原始长度 (size).
contentType:可选
给新的 Blob 赋予一个新的文档类型。这将会把它的 type 属性设为被传入的值。它的默认值是一个空的字符串。

三、组合

组合直接使用Blob() 构造函数初始化即可
语法:

const aBlob = new Blob( array, options );

array:是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings 会被编码为 UTF-8。
options:是一个可选的BlobPropertyBag字典,它可能会指定如下两个属性:

  • type:默认值为 “”,它代表了将会被放入到 blob 中的数组内容的 MIME 类型。
  • endings:默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。它是以下两个值中的一个:“native”,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 “transparent”,代表会保持 blob 中保存的结束符不变非标准

四、完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<label>
  <input id="input" type="file" onchange="fileChange(event)"/>
</label>
<script>
  // 文件大于20MB时,设置每个分片大小为20MB
  const chunkSize = 20 * 1024 * 1024;

  function fileChange(e) {
      
      
    // 定义一个数组存放所有的分片
    const chunks = [];
    // 获取文件
    const file = e.target.files[0]
    const name = file.name
    const type = file.type
    // 计算总共有多少个分片
    const totalChunks = Math.ceil(file.size / chunkSize);

    // 进行分片
    for (let i = 0; i < totalChunks; i++) {
      
      
      // 利用slice方法获取每个分片
      const start = i * chunkSize;
      // 使用Math.min避免超出文件大小
      const end = Math.min(file.size, start + chunkSize);
      const blob = file.slice(start, end, type);
      // 将每个分片添加到数组中
      chunks.push(blob);
    }
    // 在此可以分片提交文件给后端了,具体实现接口请自己解决
    console.log(chunks)

    // 合并时chunks应该从接口获取,这里默认你已经获取完文件数据并放入chunks中(不要忘记在请求时设置responseType为blob)
    // 组合
    const newBlob = new Blob(chunks, {
      
      
      type
    });
    newBlob.name = name
    console.log(newBlob)
    
    // 组合下载测试
    const aTag = document.createElement('a')
    aTag.download = name
    aTag.href = URL.createObjectURL(newBlob)
    // 自动点击创建的标签
    aTag.click()
  }
</script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/weixin_43845090/article/details/132478771