Cat_Anchor 发表于 2026-7-24 16:21:31

基岩技术教程:7.brarchive

前言

在基岩版 1.26.50.20 中,原版包开始使用 brarchive 格式打包小文件。从这个版本开始,不再可以直接解包查看原版资源,因为它们被打包成 brarchive 格式的文件了。这篇教程会详细解释 brarchive 格式。

https://klpbbs.com/static/image/hrline/line1.png

前置知识

| 基岩版的原版包

从基岩版 `1.13.0` 开始,原版有了版本管理机制,因此需要以附加包的形式,分别打包每个版本的资源。每个附加包,都代表一个原版小版本。又因为它们是原版内置的包,我们称它们为“原版包”。在新版本中,这些包位于 `/assets/assets/behavior_packs/` 或 `/assets/assets/resource_packs/`,每个名称类似 `vanilla_1.26.50` 的文件夹都代表一个原版包。

原版包属于特殊的附加包。原版游戏内容依赖于这些包,但也同时依赖于硬编码的代码。原版的行为包主要定义实体、配方、战利品表等内容,资源包主要定义实体渲染相关、纹理、声音、本地化、字体等内容。

| 文件的本质

由于技术限制,设备上存储的任何一种文件实际上是数字;要存储不是数字的东西,就要先把它转化为数字,也就是所谓的“编码”。计算机使用二进制,8 位二进制是一个字节。

一个字节的取值为从 `00000000` 到 `11111111`,一共 256 种,可以表示 0 至 255 的整数。为了方便,经常使用 2 位十六进制表示字节,也就是 `00` 到 `FF`。

文件有它的十六进制表示。比如创建一个文本文档,在里面输入“Minecraft”,使用 UTF-8 编码,我们实际上得到了

`4D 69 6E 65 63 72 61 66 74`

这样的数据。

| 文件格式

为了区分不同文件,引入了文件格式和表示文件格式的后缀。比如 `.txt` 表明这是文本文档,`.zip` 表示压缩包。但是如果我们修改了后缀,系统怎么知道这是哪种文件?

答案是魔数。在一些二进制文件格式中,文件必须以一串固定的数据开头,表明它的格式。如果我们用文本编辑器打开有效的 `.zip`,会发现它们都以 `PK` 开头,这就是魔数。

今天说的 brarchive 也是一种二进制文件格式,它也有魔数,具体数值是

`7D 27 25 B1 A0 52 70 26`

还可以写成二进制

`01111101 00100111 00100101 10110001 10100000 01010010 01110000 00100110`

或者……十进制

`125 39 37 177 160 82 112 38`

| 小端序

假设我们有一串非常长的十六进制,而且要向这个数值加 1。

`3A 1B 2C 1D 3E 2F 4A 1B 3C 1D 2E 4F 3A 2B +
00 00 00 00 00 00 00 00 00 00 00 00 00 01`

我们只好完全读取这个十六进制数字,然后在末尾加 1。由于数值很大,完全读取非常耗时且复杂。有没有办法能简化计算?

我们把十六进制倒着写,事情就轻松许多,只需要读取第一位,然后加就行了。

`2B (不需要继续读了) +
01`

这就是小端序,把数字倒着写的存储方式。一个数字,正常来说(大端序)是 `3A 1B 2C 1D 3E 2F`,小端序就是倒过来写,`2F 3E 1D 2C 1B 3A`。

虽然现在大端序和小端序的性能已经相差不大了,但是人们还是经常用小端序,这属于历史遗留问题。

https://klpbbs.com/static/image/hrline/line2.png

brarchive 格式

回到正题,`brarchive` 大概是 Bedrock Archive 的缩写,即基岩归档格式。这个文件格式可以把许多小文件打包成一个大文件,主要是因为大文件方便压缩,以及处理小文件的效率不高。

这个格式由三部分组成:文件头、目录和数据。

文件头表明这是 brarchive 文件,同时提供这个打包文件包含的文件数量。

目录存储所有文件名和文件的位置。

数据就是文件数据本身,未经压缩。

这个格式中,所有数值都是小端序存储的。

| 文件头

文件头的长度固定为 16 字节,由 8 字节的魔数、4 字节的文件数量值和 4 字节的格式版本组成。

最开头的 8 个字节是文件的魔数,固定为

`7D 27 25 B1 A0 52 70 26`

然后 4 个字节是文件数量的值,比如有一个文件,那就是 1;用小端序写出来,就是

`01 00 00 00`

文件数量也可以是 0,此时表示没有任何文件。

最后 4 个字节目前是固定的 `01 00 00 00`。

| 目录

前面说过,目录部分存储所有文件名和文件的位置,这里的“位置”指的是整个归档文件中的位置。

每个文件在目录中都占有固定的一片地方,称为一个数据块。多个数据块放在一起,就是目录。每个数据块的大小是 256 字节。

接下来,我们看看一个数据块的组成。

首先是一个字节,它表示这个文件名称的长度;然后是文件的名称。

数据块的末尾也有两个有意义的字段。倒数第八至倒数第五个字节,是这个文件数据的起始位置,也是相对于数据区域开头的偏移量。最后四个字节是文件的大小。注意,这些都是小端序的。另外,如果我们不想存储实际的文件数据,可以把这两个字段都填上 0,这样它就只是“目录”了,只有记录文件名的作用。

现在还有中间一大块地方没有用到。规定是,没有用到的地方统一填 `00`。也就是说,如果文件名比较短,我们经常能看到一个数据块中有一堆 `00`。

值得一提的是,由于我们用了 9 个字节来存储其他信息,给文件名留下的空间就是 256 - 9 = 247 个字节。是的,这个格式支持的文件名最多 247 字节。

| 数据

相对于前面几个区域的精细结构,数据区域就很粗暴,只有原始文件数据的堆叠。所有文件的数据都是堆在一起的,彼此之间没有分隔符。

---

这就是单个 brarchive 的格式了。事实上,把一堆松散的小文件打包成 brarchive 也是有讲究的。比如我们现在有一个文件夹,要打包成 brarchive,那就把文件夹里面的文件打包,打包后的文件,命名为文件夹的名称,加上 `.brarchive` 的后缀。最后,还要把打包之后的归档文件统一放进 `__brarchive` 文件夹。

比如,我们现在有 `models/blocks/a.json`,那么打包之后会出现 `__brarchive/models/blocks.brarchive`,和 `__brarchive/models.brarchive`。而后者的文件内容是非常简单的 `7D 27 25 B1 A0 52 70 26 00 00 00 00 01 00 00 00`,表明它里面并没有任何文件。这是真的,因为 models 文件夹下没有文件,只有 blocks 文件夹。`models.brarchive` 是打包“什么都没有”的结果。

https://klpbbs.com/static/image/hrline/line3.png

后记

这一期,我们讲解了 brarchive 文件格式。我也制作了一个打包或解包 brarchive 的网页,就在[这里](https://wwboq.lanzoub.com/idi473ydpfof)。


第六期 第七期 第八期
页: [1]
查看完整版本: 基岩技术教程:7.brarchive