文档入口: 设计规格 | 实现规格 | 开发说明 | 测试说明 | 覆盖矩阵 | Windows 状态 | 压测说明
xPack 不是通用序列化库,也不是单纯追求极限压缩率的冷归档格式。
xPack 的目标,是成为一套面向运行时素材包的 C 语言打包基础设施:
- 优先服务于游戏资源包、微端内容分发、运行时素材加载这类场景
- 支持包内文件的增删改查,而不是只做“一次打完就不再改”的离线归档
- 在运行时读取效率、动态写入便利性、空间回收能力之间做工程化平衡
- 统一提供位置访问、索引访问、路径访问三类对外模型
- 从设计上就考虑 Windows 与 Linux 的路径语义差异、只读布局、分卷布局与大文件边界
xPack 的核心立场很明确:
- 动态读写优先于极限压缩
save负责提交一致性,build才负责全量重构与空间回收- 它首先是“运行时资源包主线”,其次才是“可归档”
xPack 当前不是零散 API 的集合,而是已经形成一条比较完整的包管理主线。
如果从使用者视角去看,大致可以拆成下面这些层次:
xPack 支持四种包类型,但它们共享同一套底层格式,而不是四套彼此割裂的实现:
Core- 按顺序位置访问条目
- 适合最直接、最轻量的包读写
Index- 按整数索引访问条目
- 适合资源 ID、配置 ID、表项 ID 这类场景
Linux- 按路径访问
- 大小写敏感
- 保持 Linux 风格路径语义
Win32- 按路径访问
- 大小写不敏感
- 自动做 Win32 风格路径归一化
这意味着同一个库既可以服务:
- 按位置装载的简单资源包
- 按 ID 查找的索引包
- 按路径查找的素材包
- 需要区分 Linux / Windows 路径规则的跨平台分发
xPack 的主线不是“每改一个文件就重写整个包”,而是尽量让动态写入保持可控:
- 支持
add / update / remove / rename / attr - 支持包级
meta - 支持条目级
infoExt - 支持
buffered与immediate两种写入策略 - 支持只读打开、失败回滚、替换原包与重建临时路径
其中最重要的语义是:
xpkSave- 提交当前修改
- 让包重新回到一致状态
- 不会主动回收历史空洞
xpkBuild- 重构整个包
- 回收历史空洞
- 重新整理布局
- 也承担
normal / solid / volume等布局切换时的正式重建职责
这让 xPack 更适合“反复更新素材包”的工程,而不是只适合一次性归档。
xPack 当前支持这些压缩算法:
STORELZ4LZ4HCZSTDLZMA2
它不是简单把压缩当成“写包时顺手压一下”,而是把布局能力纳入正式模型:
normal mode- 普通逐文件压缩
- 适合动态读写主路径
solid mode- 数据段整体压缩
- 读取与分发友好
- 但数据段进入 solid 后,不再允许继续追加或更新文件数据
volume mode- 通过
volumeSize把单个逻辑包映射为连续分卷 - 适合受单文件大小限制的存储环境
- 通过
其中 solid 不是另一种包类型,而是一种数据段布局模式;
volume 也不是额外的索引系统,而是面向底层存储的连续视图。
xPack 不只是“能写进去”,还提供了比较完整的读取、导出和校验能力:
xpkReadToMemory / xpkReadToFilexpkVerify / xpkVerifyAllxpkEach / xpkEachMatchxpkStatGetxpkLastError / xpkLastErrorMessage
当前工程已经重点打通这些方向:
- 普通条目的直接读取与导出
solid条目的按目标切片读取与校验- 非分卷包尾段的映射式打开与解码
4GB+文件定位与大逻辑偏移分卷原始 I/O 回归- 大文件输入、导出和重建链路上的低峰值路径
换句话说,xPack 当前关注的不是“API 表面能跑”,而是让:
- 打开
- 读取
- 校验
- 导出
- 重建
这些主路径在大文件和复杂布局下仍然保持可控。
xPack 当前提供三种比较明确的工程使用方式:
xpack.c + xpack.h- 项目正式实现入口与公共头
singlehead/xpack.h- 适合单头分发或嵌入式集成
DLL / SO- 仓库内已提供 Windows 与 Linux 的构建脚本
工程上当前采用:
- 单实现入口
- 生成式公共头文件
- 独立测试入口
- vendor 压缩库独立编译
- 依赖
xrt作为基础运行时
很多打包格式强调的是:
- 压得更小
- 兼容更多历史工具
- 一次打包后长期不再修改
xPack 的优先级不同:
- 它更强调动态更新素材包时不要频繁重写全包
- 更强调运行时读取和校验主路径要清晰
- 更强调**
save与build的职责边界要稳定** - 更强调路径包、索引包、普通包要共享同一条底层主线
所以如果你的目标是:
- 做一个 ZIP 替代品
- 面向长期冷归档
- 依赖外部通用解包工具生态
那么 xPack 不是优先为这个目标设计的。
但如果你的目标是:
- 游戏资源包
- 客户端运行时素材包
- 微端内容下载与落地
- 需要多轮增删改查和重构的包格式
那么 xPack 的设计会更贴近这个问题本身。
xPack 把“改包”当成正式场景,而不是附带能力。
从打开、读取、导出、校验到重建,都是同一条工程主线,不是若干互不相干的辅助函数。
Core / Index / Linux / Win32 共享一套格式模型,而不是四套单独维护的底层实现。
STORE / LZ4 / LZ4HC / ZSTD / LZMA2、solid、volume 都在公开能力模型里,不是后加补丁。
当前实现已经对大文件输入、分卷 I/O、压缩条目导出、solid 切片校验等主路径做了持续回归和低峰值处理。
xPack 目前已经具备比较明确的工程成熟度信号:
- Windows 下,
open / close / save / build主链路已经稳定打通 Core / Index / Linux / Win32四种包类型都已有正式回归覆盖read / add / update / remove / rename / attr / meta / verify已形成完整主线solid / volume / buffered / immediate都已有跨模块集成回归4GB+文件定位与大逻辑偏移分卷 I/O 已有专门验证- Windows 已有独立压测脚本;Debian 13 主回归已通过,Linux 压测也已进入持续推进阶段
同时也要明确当前边界:
- 更长时间的发布级连续压测还在继续补
- 接近
4GB分卷上限与更大逻辑文件还需要更多真实压力验证 - 单文件数据块与编解码本身仍然受当前 block 模型边界约束
- 游戏客户端资源包
- 微端或启动器分阶段下载的内容包
- 运行时需要按路径或按 ID 查找的素材包
- 热更新、版本补丁、内容重建链路
- 需要在 Windows / Linux 间保持可控路径语义的资源分发
xPack 当前设计主线可以概括成几条非常明确的原则:
- 固定
64B文件头 - 统一
32B基础条目 +infoExt扩展模型 save负责一致性,build负责重构与压紧solid是数据段只读模式,不是另一套格式volume是存储视图,不是额外段表系统- 规格优先于实现,行为优先于历史兼容
xPack 已经不是“概念验证”阶段的小实验。
它已经具备完整主线,并且很多核心场景已经可以按正式工程思路使用。
但它当前更准确的状态仍然是:
- 主能力已经成型
- Windows 侧可用于受控生产场景
- Linux 主回归已通过并在持续补压测
- 项目仍在继续统一文档、补更大边界验证和更长时间压力验证
也就是说,xPack 当前追求的不是“能用就停”,而是把这条资源包基础设施主线继续做扎实。
下面是一个最小的 Win32 Path 包示例。
它会创建一个包、写入一个路径条目、保存、重新打开、校验并读回内容:
#include <stdio.h>
#include <string.h>
#include "xpack.h"
int main(void)
{
xpkObject pkg = NULL;
xpkOpenOptions openOpt = {0};
xpkWriteOptions writeOpt = {0};
const char* text = "hello xpack";
void* data = NULL;
uint64_t dataSize = 0;
openOpt.createIfMissing = 1;
writeOpt.compLevel = 6;
writeOpt.writePolicy = XPK_WRITE_BUFFERED;
pkg = xpkOpen("assets.xpk", &openOpt);
if (pkg == NULL) {
return 1;
}
if (xpkSetPackType(pkg, XPK_PACK_WIN32) != XPK_OK) {
goto fail;
}
if (xpkPathAddData(pkg, "assets/hello.txt", text, (uint64_t)strlen(text), &writeOpt) != XPK_OK) {
goto fail;
}
if (xpkSave(pkg) != XPK_OK) {
goto fail;
}
if (xpkClose(pkg) != XPK_OK) {
return 2;
}
pkg = NULL;
pkg = xpkOpen("assets.xpk", NULL);
if (pkg == NULL) {
return 3;
}
if (xpkVerifyAll(pkg) != XPK_OK) {
goto fail;
}
data = xpkPathReadToMemory(pkg, "assets/hello.txt", &dataSize);
if (data == NULL) {
goto fail;
}
fwrite(data, 1, (size_t)dataSize, stdout);
putchar('\n');
xpkFree(data);
data = NULL;
return xpkClose(pkg) == XPK_OK ? 0 : 4;
fail:
if (data != NULL) {
xpkFree(data);
}
if (pkg != NULL) {
fprintf(stderr, "xpack error: %s\n", xpkLastErrorMessage(pkg));
xpkClose(pkg);
}
return 5;
}如果你需要的是:
- 按位置访问:使用
xpkAddData / xpkReadToMemory - 按整数索引访问:先设为
XPK_PACK_INDEX,再使用xpkIndex* - 按 Linux 路径访问:先设为
XPK_PACK_LINUX,再使用xpkPath*
仓库里已经提供了直接可用的构建脚本。
Windows 下常用:
build_header.bat
build_GCC_DLL_x64.bat
build_GCC_TEST_x64.bat
release\x64\xpack_test.exeLinux 下常用:
./build.sh
./build_test.sh
release/x64/xpack_test all如果需要独立压测入口:
build_GCC_STRESS_x64.bat./build_stress.sh如果你希望用单头文件方式分发或嵌入,可以先生成:
build_single_head.bat或:
./build_single_head.sh生成结果位于:
singlehead/xpack.h
使用方式大致如下:
#define XRT_IMPLEMENTATION
#include "xrt.h"
#define XPACK_IMPLEMENTATION
#include "xpack.h"需要注意的是,单头版本仍然依赖外部的:
xrt.hlz4 / lz4hczstdlzma
也就是说,单头文件解决的是 xPack 自身的分发形态,不是把所有第三方实现静态内联成一个最终头文件。
- 设计规格:格式设计、产品定位、模式边界与公开能力模型
- 实现规格:工程结构、公开头生成、编译组织与错误模型
- 开发说明:目录职责、构建脚本、推荐开发流程与当前边界
- 测试说明:测试架构、helper 约定、过滤值与执行方式
- 覆盖矩阵:功能到测试文件的映射索引
- Windows 状态:Windows 当前能力结论与剩余边界
- 压测说明:Windows / Linux 压测入口、日志与历史记录
xPack 当前依赖并整合了这些基础组件:
xrtLZ4 / LZ4HCZstandardLZMA SDK
其中 xrt 负责基础运行时能力,压缩库负责 STORE / LZ4 / LZ4HC / ZSTD / LZMA2 这条编解码主线。
如果你正在寻找的不是一个“只负责离线打包”的归档工具,
而是一套能够支撑:
- 动态改包
- 运行时读取
- 路径 / 索引 / 位置三类访问
solid / volume / recompress / rebuild- Windows / Linux 资源分发
的 C 语言资源包基础设施,
那么 xPack 正在朝这个方向持续推进。