一个前端,爱跑步、爱吉他、爱做饭、爱生活、爱编程、爱南芳姑娘,爱我所爱。世间最温暖又无价的是阳光、空气与爱,愿它们能带你去更远的地方。

  • 文章
  • 心情
  • 照片墙
  • 留言板
  • 工具
  • 友链
  • biaoblog

    专注web开发技术分享

    文件中ArrayBuffer,Blob,Stream,Base64,File区别与学习

    技术 513 2024-04-24 14:39

    在前端或者后端处理文件时,多多少少会接触到这些文件的格式处理

    各自先介绍一下:

    ArrayBuffer

    • ArrayBuffer 是一种固定长度的原始二进制数据缓冲区,用于在 JavaScript 中直接处理原始二进制数据。
    • ArrayBuffer 中存储的是原始的二进制数据,以字节为单位,不包含任何编码或转换。
    • 例如,一个包含文本数据的 ArrayBuffer 对象将直接以二进制形式存储每个字符的 Unicode 码点,而不是字符本身。


    • 场景:在客户端使用 JavaScript 读取本地文件内容,并将其转换为 ArrayBuffer 进行处理。

    示例代码:

    // 读取本地文件内容并转换为 ArrayBuffer
    const fileInput = document.getElementById('file-input');
    fileInput.addEventListener('change', function(event) {
        const file = event.target.files[0];
        const reader = new FileReader();
        reader.onload = function(event) {
            const arrayBuffer = event.target.result;
            // 对 ArrayBuffer 进行处理
            // ...
        };
        reader.readAsArrayBuffer(file);
    });
    


    Blob

    • 区别:Blob 是二进制大对象,表示一个不可变的、原始数据的类文件对象。它可以包含任意类型的数据,例如文本数据、图像数据、音频数据等。
    • 使用场景:适用于文件上传、从另一个网络位置获取数据、生成临时 URL 等场景。
    // 获取文件对象并转换为 Blob
    const fileInput = document.getElementById('file-input');
    fileInput.addEventListener('change', function(event) {
      const file = event.target.files[0];
      const formData = new FormData();
      formData.append('file', file);
      // 使用 XMLHttpRequest 或 Fetch API 发送 FormData 到服务器
      // ...
    });
    

    Stream

    • Stream 是数据流的概念,在 JavaScript 中通常用于处理流式数据,比如网络请求、文件读取等。
    • 流可以是可读的、可写的或者双向的,可以动态地产生和消耗数据。
    • 流通常被用于异步处理大量数据或者连续产生的数据。
    • 场景:在客户端上传大文件时,通过流式传输(Streaming)的方式将文件数据逐块发送到服务器,避免一次性加载整个文件内容到内存中。
    const fileInput = document.getElementById('file-input');
    fileInput.addEventListener('change', function(event) {
      const file = event.target.files[0];
      const stream = file.stream(); // 获取文件流
      // 逐块读取文件数据并发送到服务器
      const reader = stream.getReader();
      function readAndSend() {
        reader.read().then(({ value, done }) => {
          if (done) {
            // 文件读取完成
            return;
          }
          // 将读取的数据块发送到服务器
          fetch('upload-url', {
            method: 'POST',
            body: value
          }).then(() => {
            // 继续读取下一块数据
            readAndSend();
          });
        });
      }
      readAndSend();
    });
    


    File

    • File 是 Blob 的子类,表示用户计算机上的一个文件。
    • 它通常由用户通过文件选择器选择,并且可以包含文件名和 MIME 类型等元数据。
    • File 对象可以像 Blob 一样使用,但它还包含了文件系统相关的信息,比如文件名、最后修改时间等。

    示例代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>文件上传示例</title>
    </head>
    <body>
      <!-- 文件上传表单 -->
      <input type="file" id="fileInput">
    
      <script>
        // 获取文件上传输入框
        const fileInput = document.getElementById('fileInput');
    
        // 添加事件监听器,当用户选择文件后触发
        fileInput.addEventListener('change', function(event) {
          // 获取用户选择的文件
          const file = event.target.files[0];
          
          // 打印文件信息
          console.log('文件名:', file.name);
          console.log('文件大小:', file.size, '字节');
          console.log('文件类型:', file.type);
          
          // 可以在这里进行进一步操作,比如读取文件内容,上传文件等
        });
      </script>
    </body>
    </html>
    


    方法大全:

    1.把字节流转为blob,并预览

    如果使用了fetch可以在拿到结果之后直接blob()即可

        const response = await fetch(url)
        const blob = await response.blob()
        const objectUrl = window.URL.createObjectURL(blob)
         //objectUrl 可以进行预览 比如
         <img src={objectUrl } />
    

    如果不想这么搞,也可以

    // 假设你有一个文件流 stream,可以是通过文件选择器或其他方式获取的
    // 这里只是一个示例,实际情况中你需要根据你的具体需求获取文件流
    const fileStream = getYourFileStreamSomehow();
    
    // 创建一个 Blob 对象
    const blob = new Blob([fileStream], { type: 'application/octet-stream' });
    
    // 现在你可以使用这个 Blob 对象做你想做的事情,比如上传到服务器
    


    2.把字节流转为File

    // 假设你有一个文件流 stream,可以是通过文件选择器或其他方式获取的
    // 这里只是一个示例,实际情况中你需要根据你的具体需求获取文件流
    const fileStream = getYourFileStreamSomehow();
    
    // 创建一个 Blob 对象
    const blob = new Blob([fileStream], { type: 'application/octet-stream' });
    
    // 使用 Blob 构造一个 File 对象
    const file = new File([blob], 'filename.ext', { type: 'application/octet-stream' });
    
    // 现在你可以使用这个 File 对象做你想做的事情,比如上传到服务器
    


    3.把字节流转为base64,并回显

    // 流转base64
    export const stream2Base64 = (stream, base64String = '') => {
      return new Promise((resolve) => {
        // 创建一个FileReader对象
        var reader = new FileReader()
        reader.onload = (e) => {
          base64String = reader.result
          resolve(base64String)
        }
        // 开始读取数据流
        reader.readAsDataURL(stream)
      })
    }
       const base64 = await stream2Base64(responseStream)
    
    //html
    <img src={base64}/>
    


    4.前端主动创建文件(text),并触发下载

        const element = document.createElement('a')
        let works_localStorage = '123'
        element.setAttribute('href', 'data:application/text;charset=utf-8,' + encodeURIComponent(works_localStorage))
        element.setAttribute('download', 'works.text')
        element.style.display = 'none'
        element.click()
            element.remove()
    


    5.执行字节流下载操作(模拟触发a标签点击)

    export const downImgFromStream = (stream, fileName) => {
      // 创建一个 <a> 标签
      var link = document.createElement('a')
      link.href = URL.createObjectURL(stream)
      // 模拟点击 <a> 标签进行下载
      link.download = `${revemoFileSuffix(fileName)}.jpg`
    
      link.click()
      // 释放 URL 对象
      URL.revokeObjectURL(link.href)
    }
    


    6.base64转file

    function base64ToFile(base64) {
      const byteString = atob(base64.split(",")[1]);
      const mimeString = base64
        .split(",")[0]
        .split(":")[1]
        .split(";")[0];
      const ab = new ArrayBuffer(byteString.length);
      const ia = new Uint8Array(ab);
    
      for (let i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
    
      return new File([ab], "1.jpg", { type: mimeString });
    }
    


    7.base64转blob

    function dataURItoBlob(dataURI) {
      var byteString = atob(dataURI.split(",")[1]);
      var mimeString = dataURI
        .split(",")[0]
        .split(":")[1]
        .split(";")[0];
      var ab = new ArrayBuffer(byteString.length);
      var ia = new Uint8Array(ab);
    
      var filename = "1.jpg";
      for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
      return new Blob([ab], { type: mimeString });
    }
    

    文章评论

    评论列表(0