前端的文件流

166 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

前言

在不借助端的能力情况下,实现本地分段读取数据分段显示。在没有特别大的性能要求或者明确提出要求的情况下一般是一次性加载所有的数据并渲染,但是如果数据量大或者手机性能不好的话就会有别的问题了。

前端的实现

假设只上传一个文件

  1. 上传文件目前前端最常见的是借助 input 的 type='file'(还有DataTransfer和HTMLCanvasElement可以实现,不介绍了)File
  2. 文件上传成功之后就会返回一个FileList 对象(event.target.files[0]里面包含了所有与文本相关的信息,包括文本流,文本流我们可能肉眼不可见)
  3. File接口是基于Blob,所以Blob有的属性和方法,File也会有,比如slice(截取源 Blob 对象中指定范围内的数据),text(返回一个promise且包含blob所有内容的UTF-8格式,就是把我们Blob转化为我们可以读懂的utf-8的格式)
  const fileDate = event.target.files[0]
  let text = await fileDate.slice(1, 10).text()
  console.log('[截取一段Blob对象]', fileDate.slice(1, 10));
  console.log('[Blob对象转化为文本]', text);

Blob

Blob/slice

File

Input/file

其它与流有关的 API

var aBlob = new Blob(array, options);

array 是一个由 ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 BlobDOMString会被编码为UTF-8, options 就不介绍了。

Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

这样说的话就是一段我们认识的文本可以通过 new Blob 可以转化为 Blob 对象

下载网页中某段文本或者日志

URL.createObjectURL() 它的参数就是 Blob 对象,用来创建一个url,可以结合a元素的 download 属性,实现一段日志或者文本的下载。

<buttom onclick="onCopyHandle()">复制文本</buttom>
function onCopyHandle() { // 创建隐藏的可***链接
    let content = `
        name: sunseekers
        role: student
        houseName: shanghai
        url: https://github.com/sunseekers
        userAgent: ${navigator.userAgent}
        log:'这里是日志内容'
    `.trim();

    let filename = 'logFiles.md'
    const eleLink = document.createElement('a');
    eleLink.download = filename;
    eleLink.style.display = 'none';

    const blob = new Blob([content]);
    eleLink.href = URL.createObjectURL(blob); // 字符内容转变成blob地址

    document.body.appendChild(eleLink);
    eleLink.click(); // 触发点击
    document.body.removeChild(eleLink); // 然后移除

    Message.success('日志下载成功')
};

本地预览上传图片

图片可以用img标签显示也可以用canvas画,看需求来决定。

<body>
  <div class="index">
    <input type="file" value="上传文件">
    <img width="100" height="100" />
  </div>
</body>
<script>
  let inputEle = document.querySelector("input")
  let img = document.querySelector("img")

  inputEle.addEventListener('change', async function (event) {
    const fileDate = event.target.files[0]
    const fileReader = new FileReader()
    fileReader.readAsDataURL(fileDate)
    fileReader.onload = e => {
      img.src = e.target.result
    }
  })
</script>

API FileReader

FileReader