前端系列之: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);
| 区别 | Blob | Base64 |
|---|---|---|
| 存储方式 | 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 与二进制 什么是二进制? 二进制是计算机数据的基本表示形式,只使用 0 和 1 两个数字来表示数值。任何类型的数据(无论是文本、图片、音频文件等)都可以通过二进制表示。 什么是 Blob? 全称 Binary Large Object&a…...
【项目管理】基于 C 语言的 QQ 聊天室实现(TCP + 多线程 + SQLite3)
基于 C 语言的 QQ 聊天室(TCP + 多线程 + SQLite3) 项目功能基础功能: 登录、注册、添加好友、私聊、创建群聊、群聊扩展功能: 删除好友、注销账号、好友在线状态、群管理(拉人/踢人)、VIP 特权、邮件通知等 功能介绍:模拟QQ聊天客户端:登录界面:1、登录2、注册 //将用…...
Apache Flink:实时数据流处理的终极武器
Apache Flink:实时数据流处理的终极武器 在当今这个数据驱动的世界,实时数据流处理已经成为各行各业的核心需求。从金融风控到电商推荐,从物联网监控到网络安全,毫秒级的响应能力决定了一家公司在市场中的竞争力。而在众多流式计…...
点云处理入门--PointNetPointNet++论文与代码详解
基础知识 点云数据: 点云是一种通过三维扫描设备或计算机图形学技术获取的三维空间数据,通常由一系列点组成,每个点包含其在三维空间中的坐标(如 x,y,z),有时还可能包含颜色、强度等附加信息。 介绍几种常…...
通过Nginx负载均衡+Keepalived实现业务高可用
通过Nginx负载均衡和Keepalived可以实现业务的高可用,以下是详细的实现步骤: 环境准备 假设我们有3台服务器,IP地址分别为: 服务器1(Nginx Keepalived 主节点):192.168.1.100服务器2&#x…...
Spark技术系列(三):Spark算子全解析——从基础使用到高阶优化
Spark技术系列(三):Spark算子全解析——从基础使用到高阶优化 1. 算子核心概念与分类体系 1.1 算子本质解析 延迟执行机制:转换算子构建DAG,行动算子触发Job执行任务并行度:由RDD分区数决定(可通过spark.default.parallelism全局配置)执行位置优化:基于数据本地性的…...
ES6模块化详解:导入与导出方式
在现代 JavaScript 开发中,模块化是代码管理和组织的重要工具。ES6(ECMAScript 2015)引入了模块化的概念,通过 import 和 export 来组织代码,使得模块的管理变得更加清晰和简洁。本文将详细介绍 ES6 中的各种模块导入导…...
每日学习Java之一万个为什么?[MySQL面试篇]
分析SQL语句执行流程中遇到的问题 前言1 MySQL是怎么在一台服务器上启动的2 MySQL主库和从库是同时启动保持Alive的吗?3 如果不是主从怎么在启动的时候保证数据一致性4 ACID原则在MySQL上的体现5 数据在MySQL是通过什么DTO实现的6 客户端怎么与MySQL Server建立连接…...
常用空间数据结构对比
空间数据结构是用来组织和查询多维空间数据的算法结构。它们在地理信息系统 (GIS)、计算机图形学、机器人导航、机器学习等领域非常重要。以下是几种常见空间数据结构的对比: 1. 四叉树(Quadtree) 适用场景:二维空间数据&#x…...
AnythingLLM+LM Studio本地知识库构建
前置操作: 已经安装以下软件,并配置后: DeepSeek-R1-Distill-Llama-8B-Q4_K_M.ggufLM-Studio-0.3.10-6-x64 软件准备: 下载AnythingLLM:AnythingLLM | The all-in-one AI application for everyone 点击"Dow…...
使用 Java 更新 Word 文档中的图表数据-超详细
使用 Java 更新 Word 文档中的图表数据 在日常的工作中,尤其是在数据分析和报告自动化的场景中,可能会遇到需要定期更新 Word 文档中的图表数据的需求。比如,生成数据报告时,我们需要在图表中更新一些动态的数据值。今天…...
Qt常用控件之下拉框QComboBox
下拉框QComboBox QComboBox 是一个下拉框控件。 1. QComboBox属性 属性说明currentText当前选中的文本。currentIndex当前选中的条目下标(从 0 开始,如果没有条目被选中则该值为 -1)。editable是否允许被修改。为 true 时,QCom…...
Qt 中集成mqtt协议
一,引入qmqtt 库 我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台时 方便,直接编译就行了。 原始仓库路径:https://github.com/emqx/qmqtt/tree/master 二,使用 声明一个单例类,将订阅到…...
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是什么? 官方地址:Props | Vue.js 在 Vue 中,props 是父组件向子组件传递数据的一种机制。 props 是子组件中定义的自定义属性,父组件通过这些属性向子组件传递数据。 它们是单向数据流的一部分,意味着数据只能…...
Ecode前后端传值
说明 在泛微 E9 系统开发过程中,使用 Ecode 调用后端接口并进行传值是极为常见且关键的操作。在上一篇文章中,我们探讨了 Ecode 调用后端代码的相关内容,本文将深入剖析在 Ecode 中如何向后端传值,以及后端又该如何处理接收这些值…...
【Linux】进程状态(二)
目录 前言: 一、进程状态: 1.运行状态(时间片) 2.阻塞状态 3.阻塞挂起状态 二、Linux进程状态: 1.运行状态(R)和阻塞状态(S) 2.深度睡眠状态(D) 3.停止状态(T) 3.1使进程在后台运行 4.追踪暂停状态(t) 5.死亡状态(X)和僵尸状态…...
domain 网络安全 网络安全域
🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 文章目录 1、域的概述 1.1、工作组与域1.2、域的特点1.3、域的组成1.4、域的部署概述1.5、活动目录1.6、组策略GPO 2、域的部署实验 2.1、建立局域网…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
