当前位置: 首页 > news >正文

前端系列之:Blob

Blob 与二进制

什么是二进制?

二进制是计算机数据的基本表示形式,只使用 0 和 1 两个数字来表示数值。任何类型的数据(无论是文本、图片、音频文件等)都可以通过二进制表示。

什么是 Blob?

全称 Binary Large Object,二进制类型的大对象。是一种数据类型,用来存储二进制数据。

怎么解释 JavaScript 的数据类型中并没有 Blob 类型?

Blob 是用来存储二进制数据的,而二进制又是计算机的基本表示形式,所以很多编程语言(如 java)和数据库(如 mysql)都是支持 Blobl 的。

但对于前端 Blob 而言,Blob 是由浏览器环境(或类浏览器环境,如 WebView 或 React Native)提供的,而不是 JavaScript 语言本身的一部分。Blob 是 Web API 的一部分,用于表示不可变的二进制数据。所以 Blob 对象只有在浏览器环境中才能正常使用。如果在非浏览器环境(如 Node.js 环境)中,默认情况下是没有 Blob 对象的。

Blob 表示不可变的、原始的二进制数据。这句话怎么理解?

“不可变” 表示一旦 Blob 对象被创建,其内容就不能被修改。如果你需要修改 Blob 中的数据,通常的做法是创建一个新的 Blob 对象,而不是直接更改原始的 Blob 对象。

Blob 用途

  • 数据库:在数据库中,Blob 用来存储图像、音频文件等二进制数据。例如,关系型数据库中的 BLOB 类型字段用来保存图像或其他多媒体文件。

  • 文件存储:Blob 通常用于大文件(如视频、音频、图像等)的存储,并且通常以二进制格式存在。

  • Web 开发(本文重点):

    • 上传文件到服务器。

    • 从服务器下载文件。

    • 在浏览器中生成文件并下载。

    • 处理图片、视频等二进制数据。

Blob 构造函数

要从其他非 Blob 对象和数据构造一个 Blob,需要使用 Blob() 构造函数。Blob 对象一旦创建,其内容不可更改。

let blob = new Blob(array, options);
  • array:这是一个数组,可以包含多个数据部分,通常是 ArrayBuffer(二进制数据)、Array(字符串数据)等。

  • options:一个可选对象

    • type:指定 Blob 对象的 MIME 类型。MIME 类型是一种标准,用于表示文档、文件或字节流的性质和格式。例如,"text/plain" 表示纯文本文件,"image/jpeg" 表示 JPEG 格式的图片。如果没指定,默认是 "" 空字符串。

    • endings:指定在创建 Blob 对象时如何处理换行符。它有两个可选值:

      • transparent(默认值):不转换换行符,保留原始数据中的换行符。

      • native:将换行符转换为当前操作系统的本地换行符(例如,在 Windows 上是 \r\n,在 Unix/Linux 上是 \n)。

示例:

let text = "Hello, world!";
let blob = new Blob([text], { type: "text/plain" });
let url = URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = "hello.txt";
a.click();
URL.revokeObjectURL(url)

Blob 属性/方法

属性/方法描述
size获取 Blob 的大小(字节数)
type获取 Blob 的类型(MIME类型)
slice()Blob 分片。当你处理大文件时,可能需要将文件拆分成多个小块进行处理或上传。该方法可以让你提取文件的一部分并进行操作
stream()返回一个 ReadableStream 对象,读取它将返回包含在 Blob 中的数据
arrayBuffer()返回一个 ReadableStream 对象,读取它将返回包含在 Blob 中的数据

slice():Blob 分片,其有三个参数:

  • start:设置切片的起点,即切片开始位置。默认值为 0,即从第一个字节开始

  • end:设置切片的结束点,会对该位置之前的数据进行切片。默认值为blob.size

  • contentType:设置新 blob 的 MIME 类型。如果省略 type,则默认为 blob 的原始值

let text = "Hello, world!";
let blob = new Blob([text], { type: "text/plain" });
const subBlob = blob.slice(0, 5);
let url = URL.createObjectURL(subBlob);
let a = document.createElement("a");
a.href = url;
a.download = "hello.txt";
a.click();
URL.revokeObjectURL(url)// 此时下载的文件内容只有 Hello

Blob 与 URL

这里只介绍 URL.createObjectURL(blob); 方法。

创建一个 Blob 对象后,我们可以使用 createObjectURL 方法将其转换为 URL 地址。该 URL 可以用于在浏览器中显示图片、下载文件等。

<template><input type="file" id="fileInput" multiple="multiple"><img :src="src">
</template><script setup>
import { onMounted, ref } from 'vue';
const src = ref(null)onMounted(() => {const fileInput = document.getElementById("fileInput");fileInput.onchange = (e) => {const file = e.target.files[0]let url = URL.createObjectURL(file);console.log(url)src.value = url}
})
</script>

createObjectURL 注意事项:

  • 使用完 URL 后,需要手动释放,否则会导致内存泄漏 URL.revokeObjectURL(url);

  • IE 浏览器不支持 createObjectURL 方法

下载文件上完整示例:

api.downloadFile(params).then(res=>{let blob = new Blob([res.result]);if (window.navigator.msSaveOrOpenBlob) {// 兼容 IEwindow.navigator.msSaveOrOpenBlob(blob, 'hello.txt');} else {let url = window.URL.createObjectURL(blob);let a = document.createElement("a");a.href = url;a.download = "hello.txt";document.body.appendChild(a)a.click();document.body.removeChild(a)window.URL.revokeObjectURL(url)}
})

Blob 与 Base64

Base64 可以将二进制数据转换为为 ASCII 字符串。这样可以方便地在文本协议(如 HTTP、JSON)中传输二进制数据(实际传输的是字符串)。

// 将字符串编码为 Base64:
const text = 'Hello, world!';
const base64String = btoa(text);
console.log(base64String);  // 输出 Base64 编码的字符串// 将 Base64 字符串解码为原始字符串:
const decodedText = atob(base64String);
console.log(decodedText);  // 输出 'Hello, world!'// 通过 FileReader 将 Blob 转换为 Base64 字符串:
const blob = new Blob(['Hello, world!'], { type: 'text/plain' });
const reader = new FileReader();reader.onloadend = function() {const base64String = reader.result.split(',')[1];  // 获取 Base64 部分console.log(base64String);
};
reader.readAsDataURL(blob);
区别BlobBase64
存储方式Blob 用于存储原始的二进制数据Base64 是将二进制数据转为文本编码的字符串
性能直接存储二进制数据,不会占用额外的空间,因此它处理大文件时性能更好会增加约 33% 的数据大小,因为每个 3 字节的二进制数据会被编码为 4 字节的 Base64 字符串
应用场景适合处理文件上传/下载适合将二进制数据嵌入到 HTML 或 JavaScript 中(如图片在 HTML 中的嵌入)

Blob 与 ArrayBuffer

Blob 和 ArrayBuffer 都是用于处理二进制数据。ArrayBuffer 是底层的二进制数据存储容器,而 Blob 是一种更高级的类文件对象,它可以包含 ArrayBuffer。

  • ArrayBuffer 适合处理小块的二进制数据,因为它在内存中是连续存储的,读写速度较快。但如果数据量过大,可能会导致内存占用过高。

  • Blob 更适合处理大文件或流式数据,因为它不需要将整个数据加载到内存中。浏览器可以对 Blob 进行优化,例如分块读取和处理数据,从而减少内存占用。

ArrayBuffer 特点:

  • 存储原始的二进制数据。

  • 长度固定,创建后无法更改。

  • 需要通过视图(如 Uint8Array、DataView 等)来读写数据。

在实际开发中,它们的使用场景常常是互补的。
ArrayBuffer 用于在内存中高效地处理和操作二进制数据,而 Blob 则更适合用于文件的存储、传输和展示等场景。
例如,在处理图片数据时,先将图片数据读取到 ArrayBuffer 中进行处理(如裁剪、压缩等),然后再将处理后的 ArrayBuffer 转换为 Blob 对象,通过 URL.createObjectURL() 生成临时 URL 展示图片或进行文件下载。

ArrayBuffer 转 Blob:当你有一个 ArrayBuffer 并且想把它当作一个文件来处理(比如下载、上传等)时,可以将其转换为 Blob 对象。

const buffer = new ArrayBuffer(16);
// 创建一个包含 ArrayBuffer 数据的 Blob 对象
const blob = new Blob([buffer], { type: 'application/octet-stream' });

Blob 转 ArrayBuffer:当你需要对 Blob 中的数据进行底层操作时,可以将 Blob 转换为 ArrayBuffer。通常使用 FileReader 对象来完成这个转换。

const text = 'Hello, World!';
const blob = new Blob([text], { type: 'text/plain' });
const reader = new FileReader();
reader.readAsArrayBuffer(blob);
reader.onload = function() {const buffer = reader.result;console.log(buffer);
};

Blob 与 File

File 是 Blob 的一个子类,扩展了 Blob 的功能。它不仅包含数据本身,还包含文件的元数据(如文件名、类型等)。

在 JavaScript 中,主要有两种方法来获取 File 对象:

  • 元素上选择文件后返回的 FileList 数组,该数组的每个元素都是一个 File 对象

    <template><input type="file" id="fileInput" multiple="multiple">
    </template><script setup>
    import { onMounted } from 'vue';onMounted(() => {const fileInput = document.getElementById("fileInput");fileInput.onchange = (e) => {console.log(e.target.files);}
    })
    </script>
    

在这里插入图片描述

  • 文件拖放操作生成的 DataTransfer 对象

    <template><div id="drop-zone"></div>
    </template><script setup>
    import { onMounted } from 'vue';onMounted(() => {const dropZone = document.getElementById("drop-zone");dropZone.ondragover = (e) => {e.preventDefault();}dropZone.ondrop = (e) => {e.preventDefault();const files = e.dataTransfer.files;console.log(files)}
    })
    </script><style scoped>
    #drop-zone {margin: auto;width: 100px;height: 100px;border: 1px solid #000;
    }
    </style>
    

    打印内容同上。

Blob 与 Streams

Blob 的局限性:Blob 对象是一次性读取整个数据,对于大文件来说,可能会占用大量的内存,导致性能问题。

Stream(数据流)是一种按顺序读取和写入数据的方式,通常用于处理大量数据而不将其一次性加载到内存中。Streams 可以通过分块逐步传输数据,使得程序能够在处理数据时节省内存资源。

使用场景:

  • 文件读取与写入:流被广泛应用于文件的处理,尤其是当文件很大,不能一次性加载到内存时,流式处理可以分段读取并处理数据。

  • 网络传输:流用于数据的实时传输,尤其是在处理音视频流、网络请求响应等场景下。

  • 处理大数据:Stream 能够在读取大数据时逐块处理,而不是将整个数据加载到内存中,这样能节省内存并提高效率。

特点:

  • 数据按块(chunk)逐步传输。

  • 节省内存,特别适用于大文件的读取与写入。

  • 异步操作,有助于处理 I/O 操作。

Blob 与 FileReader

FileReader 是一个用于异步读取 Blob 或 File 对象中内容的 API,并且可以将 Blob/File 读取为不同的格式(如文本、Base64 等)。

示例:

<template><input type="file" id="fileInput" multiple="multiple">
</template><script setup>
import { onMounted } from 'vue';onMounted(() => {const fileInput = document.getElementById("fileInput");fileInput.onchange = (e) => {console.log(e.target.files);const file = e.target.files[0]if (file) {const reader = new FileReader();reader.onload = function (e) {console.log('文件内容:', e.target.result);};reader.readAsText(file);}}
})// 这种写法也是一样的
onMounted(() => {const fileInput = document.getElementById("fileInput");const reader = new FileReader();fileInput.onchange = (e) => {reader.readAsText(e.target.files[0]);}reader.onload = (e) => {console.log('文件内容:', e.target.result);}
})
</script>

在这里插入图片描述

上传的文件就是最开始的 hello.txt。

FileReader 方法/事件

Web API > FileReader

方法描述
readAsArrayBuffer()开始读取指定的 Blob 中的内容,一旦完成,result 属性中将包含一个表示文件数据的 ArrayBuffer 对象。
readAsBinaryString()…result 属性中将包含一个表示文件中的原始二进制数据的字符串。
readAsDataURL()…result 属性中将包含一个表示文件数据的 data: URL
readAsText()…result 属性中将包含一个表示所读取的文件内容的字符串
事件描述
abort该事件在读取操作被中断时触发
error该事件在读取操作发生错误时触发
load该事件在读取操作完成时触发
loadend读取完成时触发,无论成功与否
loadstart读取开始时触发
progress读取数据时定期触发

相关文章:

前端系列之:Blob

Blob 与二进制 什么是二进制&#xff1f; 二进制是计算机数据的基本表示形式&#xff0c;只使用 0 和 1 两个数字来表示数值。任何类型的数据&#xff08;无论是文本、图片、音频文件等&#xff09;都可以通过二进制表示。 什么是 Blob&#xff1f; 全称 Binary Large Object&a…...

【项目管理】基于 C 语言的 QQ 聊天室实现(TCP + 多线程 + SQLite3)

基于 C 语言的 QQ 聊天室(TCP + 多线程 + SQLite3) 项目功能基础功能: 登录、注册、添加好友、私聊、创建群聊、群聊扩展功能: 删除好友、注销账号、好友在线状态、群管理(拉人/踢人)、VIP 特权、邮件通知等 功能介绍:模拟QQ聊天客户端:登录界面:1、登录2、注册 //将用…...

Apache Flink:实时数据流处理的终极武器

Apache Flink&#xff1a;实时数据流处理的终极武器 在当今这个数据驱动的世界&#xff0c;实时数据流处理已经成为各行各业的核心需求。从金融风控到电商推荐&#xff0c;从物联网监控到网络安全&#xff0c;毫秒级的响应能力决定了一家公司在市场中的竞争力。而在众多流式计…...

点云处理入门--PointNetPointNet++论文与代码详解

基础知识 点云数据&#xff1a; 点云是一种通过三维扫描设备或计算机图形学技术获取的三维空间数据&#xff0c;通常由一系列点组成&#xff0c;每个点包含其在三维空间中的坐标&#xff08;如 x,y,z&#xff09;&#xff0c;有时还可能包含颜色、强度等附加信息。 介绍几种常…...

通过Nginx负载均衡+Keepalived实现业务高可用

通过Nginx负载均衡和Keepalived可以实现业务的高可用&#xff0c;以下是详细的实现步骤&#xff1a; 环境准备 假设我们有3台服务器&#xff0c;IP地址分别为&#xff1a; 服务器1&#xff08;Nginx Keepalived 主节点&#xff09;&#xff1a;192.168.1.100服务器2&#x…...

Spark技术系列(三):Spark算子全解析——从基础使用到高阶优化

Spark技术系列(三):Spark算子全解析——从基础使用到高阶优化 1. 算子核心概念与分类体系 1.1 算子本质解析 延迟执行机制:转换算子构建DAG,行动算子触发Job执行任务并行度:由RDD分区数决定(可通过spark.default.parallelism全局配置)执行位置优化:基于数据本地性的…...

ES6模块化详解:导入与导出方式

在现代 JavaScript 开发中&#xff0c;模块化是代码管理和组织的重要工具。ES6&#xff08;ECMAScript 2015&#xff09;引入了模块化的概念&#xff0c;通过 import 和 export 来组织代码&#xff0c;使得模块的管理变得更加清晰和简洁。本文将详细介绍 ES6 中的各种模块导入导…...

每日学习Java之一万个为什么?[MySQL面试篇]

分析SQL语句执行流程中遇到的问题 前言1 MySQL是怎么在一台服务器上启动的2 MySQL主库和从库是同时启动保持Alive的吗&#xff1f;3 如果不是主从怎么在启动的时候保证数据一致性4 ACID原则在MySQL上的体现5 数据在MySQL是通过什么DTO实现的6 客户端怎么与MySQL Server建立连接…...

常用空间数据结构对比

空间数据结构是用来组织和查询多维空间数据的算法结构。它们在地理信息系统 (GIS)、计算机图形学、机器人导航、机器学习等领域非常重要。以下是几种常见空间数据结构的对比&#xff1a; 1. 四叉树&#xff08;Quadtree&#xff09; 适用场景&#xff1a;二维空间数据&#x…...

AnythingLLM+LM Studio本地知识库构建

前置操作&#xff1a; 已经安装以下软件&#xff0c;并配置后&#xff1a; DeepSeek-R1-Distill-Llama-8B-Q4_K_M.ggufLM-Studio-0.3.10-6-x64 软件准备&#xff1a; 下载AnythingLLM&#xff1a;AnythingLLM | The all-in-one AI application for everyone 点击"Dow…...

使用 Java 更新 Word 文档中的图表数据-超详细

使用 Java 更新 Word 文档中的图表数据 在日常的工作中&#xff0c;尤其是在数据分析和报告自动化的场景中&#xff0c;可能会遇到需要定期更新 Word 文档中的图表数据的需求。比如&#xff0c;生成数据报告时&#xff0c;我们需要在图表中更新一些动态的数据值。今天&#xf…...

Qt常用控件之下拉框QComboBox

下拉框QComboBox QComboBox 是一个下拉框控件。 1. QComboBox属性 属性说明currentText当前选中的文本。currentIndex当前选中的条目下标&#xff08;从 0 开始&#xff0c;如果没有条目被选中则该值为 -1&#xff09;。editable是否允许被修改。为 true 时&#xff0c;QCom…...

Qt 中集成mqtt协议

一&#xff0c;引入qmqtt 库 我是将整个头文件/源文件都添加到了工程中进行编译&#xff0c;这样 跨平台时 方便&#xff0c;直接编译就行了。 原始仓库路径&#xff1a;https://github.com/emqx/qmqtt/tree/master 二&#xff0c;使用 声明一个单例类&#xff0c;将订阅到…...

2024年第十五届蓝桥杯大赛软件赛省赛Python大学A组真题解析

文章目录 试题A: 拼正方形(本题总分:5 分)解析答案试题B: 召唤数学精灵(本题总分:5 分)解析答案试题C: 数字诗意解析答案试题A: 拼正方形(本题总分:5 分) 【问题描述】 小蓝正在玩拼图游戏,他有7385137888721 个2 2 的方块和10470245 个1 1 的方块,他需要从中挑出一些…...

AI大模型-提示工程学习笔记19-自我反思

目录 1. 自我反思的核心思想 (1) LLM 的局限性 (2) Reflexion 的解决方案 2. Reflexion 的工作流程 (1) 任务输入 (2) 初始生成 (3) 反思 (Reflection) (4) 调整与改进 (5) 迭代 (6) 结果输出 3. Reflexion 的关键组件 (1) 大语言模型 (LLM) (2) 反思者 (Reflector…...

GaussDB 学习实战指南:从部署到高并发优化的全流程解析

引言 GaussDB 作为华为推出的高性能分布式数据库,凭借其 分布式架构、高可用性、云原生支持 等特性,成为企业级应用的核心选择。本文将以 实战操作为核心,覆盖 集群部署、数据分片、性能调优、容灾备份、云上迁移 五大场景,通过真实案例与代码示例,助你快速掌握 GaussDB …...

vue3 Props的使用

Props是什么&#xff1f; 官方地址&#xff1a;Props | Vue.js 在 Vue 中&#xff0c;props 是父组件向子组件传递数据的一种机制。 props 是子组件中定义的自定义属性&#xff0c;父组件通过这些属性向子组件传递数据。 它们是单向数据流的一部分&#xff0c;意味着数据只能…...

Ecode前后端传值

说明 在泛微 E9 系统开发过程中&#xff0c;使用 Ecode 调用后端接口并进行传值是极为常见且关键的操作。在上一篇文章中&#xff0c;我们探讨了 Ecode 调用后端代码的相关内容&#xff0c;本文将深入剖析在 Ecode 中如何向后端传值&#xff0c;以及后端又该如何处理接收这些值…...

【Linux】进程状态(二)

目录 前言&#xff1a; 一、进程状态&#xff1a; 1.运行状态(时间片) 2.阻塞状态 3.阻塞挂起状态 二、Linux进程状态&#xff1a; 1.运行状态(R)和阻塞状态(S) 2.深度睡眠状态(D) 3.停止状态(T) 3.1使进程在后台运行 4.追踪暂停状态(t) 5.死亡状态(X)和僵尸状态…...

domain 网络安全 网络安全域

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 文章目录 1、域的概述 1.1、工作组与域1.2、域的特点1.3、域的组成1.4、域的部署概述1.5、活动目录1.6、组策略GPO 2、域的部署实验 2.1、建立局域网&#xf…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...