前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库Blob File ArrayBuffer 二进制数据关系
JavaScript数据处理

Blob、File、ArrayBuffer 和 TypedArray 之间是什么关系?

File 是 Blob 的子类,多了 name、lastModified 这些文件信息。Blob 是一块不可修改的字节,适合上传、下载、切片。要读写具体字节,得先转成 ArrayBuffer,再用 Uint8Array 这类类型化数组去看,它们只是同一块内存的不同解读方式。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#数据处理
先看核心答案读代码示例
理解线索

从文件到字节的四层

  1. File在 Blob 基础上加了 name 和 lastModified 等文件信息
  2. Blob不可修改的字节块,带 size 和 type,能切片和读取
  3. ArrayBuffer 和视图ArrayBuffer 存字节,Uint8Array 和 DataView 决定怎么读

它们不是四种互相替代的格式,而是一条链:文件来源、字节容器、内存、解读方式,每一层解决不同的问题。

核心回答

先记住这个答案

这四个类型是一条从文件到字节的链。File 继承自 Blob,是 Blob 加上文件名 name 和修改时间 lastModified,所以任何接收 Blob 的接口也能接收 File。Blob 表示一块不可修改的原始数据,有大小 size 和 MIME 类型 type,可以切片、上传、生成下载链接,但不能直接读里面的字节。要读字节,就用 blob.arrayBuffer() 转成 ArrayBuffer,它是一段可读写的内存。ArrayBuffer 自己也不能按下标访问,要通过 Uint8Array、Float32Array 这类类型化数组,或者 DataView 去读写,它们决定了把这些字节当成什么类型来解读。

  • File 继承 Blob,能用 Blob 的所有方法
  • Blob 不可修改,ArrayBuffer 是可读写的内存
  • ArrayBuffer 不能直接读写,要通过视图访问
  • 同一个 ArrayBuffer 上的多个视图共享内存

读取文件头:四层一起用

用户用 <input type="file"> 选了一个文件,想读前 4 个字节判断它是不是 PNG。

从 File 一层层拿到字节JavaScript
async function readSignature(file) {
  console.log(file.name, file.type, file.size)   // File 的文件信息

  const header = file.slice(0, 4)                // 继承自 Blob 的方法,返回 Blob
  const buffer = await header.arrayBuffer()      // 转成可读写的内存
  const bytes = new Uint8Array(buffer)           // 按一个字节一个元素来读

  return [...bytes].map(b => b.toString(16).padStart(2, '0')).join(' ')
}
// 传入一个 PNG 文件,返回 '89 50 4e 47'

每一层干一件事。file.slice 是 File 从 Blob 继承来的方法,切出前 4 个字节得到一个新的 Blob,不会把整个文件读进内存。arrayBuffer() 把这 4 个字节读成内存。Uint8Array 把内存按无符号 8 位整数来解读,每个元素正好是一个字节。 注意 file.type 是浏览器根据扩展名猜出来的,改个扩展名就变了,不能用来做安全校验。读文件头也只适合给用户提示,服务端要重新检查。

ArrayBuffer 和类型化数组的关系

ArrayBuffer 只是一段字节,它不知道这些字节代表图片、音频还是数字。类型化数组是在它上面加一层「怎么读」的规则:Uint8Array 每个元素占 1 个字节,Int32Array 每 4 个字节当一个整数,Float32Array 每 4 个字节当一个浮点数。

多个视图共享同一块内存
同一个 ArrayBuffer 上可以同时创建多个视图。比如 new Uint8Array(buffer) 和 new Uint32Array(buffer) 指向同一块内存,通过一个视图改了字节,另一个视图读到的值也会变。视图本身不存数据,要复制数据得调用 slice()。 还可以只看其中一段:new Uint8Array(buffer, 4, 8) 从第 4 个字节开始看 8 个字节,常用于解析文件头、网络协议这类有固定结构的数据。
回答前,多想一步

容易答错的地方

认为 File 和 Blob 是两个不相关的类型
File 就是一种 Blob,所以 file instanceof Blob 为 true。FormData.append、URL.createObjectURL、fetch 的请求体这些接收 Blob 的地方,都可以直接传 File。
以为改了 ArrayBuffer 之后 Blob 也会变
blob.arrayBuffer() 读出的是一份新内存,和 Blob 没有关联。反过来用 new Blob([buffer]) 创建 Blob 时,数据也是在那一刻复制进去的,之后改 buffer 不会影响这个 Blob。
试着用自己的话回答

面试官还会怎么问?

blob.slice() 会复制数据吗?

规范只规定它返回一个包含指定范围的新 Blob,没规定要不要物理复制。浏览器通常不会马上复制,而是记录范围,共享底层数据。因为 Blob 不可修改,共享也是安全的,调用方不需要关心。

怎样把 ArrayBuffer 变回 Blob 或 File?

用 new Blob([buffer], { type: 'image/png' }),要文件名就用 new File([buffer], 'a.png', { type: 'image/png' })。type 要自己填对,浏览器不会根据内容推断。

ArrayBuffer 和 Node.js 的 Buffer 是什么关系?

Node.js 的 Buffer 是 Uint8Array 的子类,底层也是 ArrayBuffer。所以 Buffer 能用类型化数组的方法,也可以通过 buf.buffer 拿到底层的 ArrayBuffer,但要注意 byteOffset,小的 Buffer 可能共享一个更大的内存池。

从一道题,走向一组知识

把知识连起来

数据处理

解析二进制协议时,为什么要用 DataView 而不是 Uint16Array?

同一个 ArrayBuffer 用 DataView 读多字节整数时要指定字节序,这是类型化数组做不到的。

数据处理

new Date 传数字、传字符串、传多个参数,分别按什么时区算?

File 的 lastModified 是毫秒时间戳,要展示成日期就会用到 new Date 的各种参数形式。

参考资料

  • JavaScript:数据处理参考资料
  • MDN:File
  • MDN:TypedArray

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 读取文件头:四层一起用
  3. ArrayBuffer 和类型化数组的关系
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑