引言
在 PDF 文件中,每一个对象(object)都可能被其他对象引用,例如页面树中的 /Page
、字体对象、内容流等。为了快速定位这些对象,PDF 在文件尾部引入了 交叉引用表(Cross-Reference Table,简称 xref) 与 trailer 结构。
这两者共同构成了 PDF 文件的索引机制:
- xref 表 用于精确记录对象在文件中的物理偏移位置;
- trailer 用于提供文档入口点(如
/Root
)和全局信息。
1. 传统交叉引用表(Cross-Reference Table)
1.1 基本结构
一个典型的 xref 表位于文件尾部,由以下几部分组成:
xref
0 6
0000000000 65535 f
0000000017 00000 n
0000000081 00000 n
0000000145 00000 n
0000000200 00000 n
0000000275 00000 n
含义说明:
xref
:表示交叉引用表开始。0 6
:表示从对象号 0 开始,共有 6 个条目。- 每行条目固定 20 个字符,包括:
- 字节偏移量(10 位,前导零补齐):对象在文件中的起始位置;
- 生成号(5 位,前导零补齐):用于对象的版本管理;
- 状态标识 (1 个字符 + 换行):
n
表示对象被使用(in-use entry);f
表示对象空闲(free entry)。
1.2 特殊规则
- 第 0 号对象 必须始终是空闲的,生成号固定为
65535
。
它是空闲对象链表的头节点。 - 空闲对象通过偏移量字段形成一个单向链表,最后指向对象 0。
- xref 表之后紧跟 trailer,提供全局信息。
2. Trailer 字典
trailer 紧随 xref 表之后,格式如下:
shell
trailer
<<
/Size 6
/Root 1 0 R
/Info 2 0 R
/ID [<81b14e...> <81b14e...>]
>>
startxref
310
%%EOF
解释:
/Size
:对象总数(即最大对象号 + 1);/Root
:文档目录对象,整个 PDF 的入口;/Info
:文档信息对象(标题、作者等);/ID
:文件标识符数组(两个 16 字节值);startxref
:指出 xref 表的起始字节偏移;%%EOF
:文件结束标记。
在增量更新时,还可能包含 /Prev
,指向上一个 xref 的位置。
3. 流式交叉引用表(Cross-Reference Stream)
从 PDF 1.5 开始,可以用 交叉引用流 替代传统的 xref 表与 trailer。
它的本质是一个 /Type /XRef
的流对象,字典部分包含 trailer 信息,流部分存储交叉引用条目。
3.1 示例
css
12 0 obj
<<
/Type /XRef
/Size 21
/W [1 2 1]
/Index [0 21]
/Root 1 0 R
/Info 2 0 R
/ID [<81b14e...> <81b14e...>]
/Length 64
/Filter /FlateDecode
>>
stream
... 二进制数据 ...
endstream
endobj
3.2 关键字典项
/Size
:对象总数;/Index
:指定对象号范围,例如[0 21]
表示 0--20;/W [w0 w1 w2]
:指定条目字段宽度:- 字段 1 :条目类型
- 0 = free entry
- 1 = 普通对象(存储偏移量)
- 2 = 压缩对象(存储在对象流中)
- 字段 2:根据类型不同,可能是偏移量或对象流号;
- 字段 3:生成号或对象流内的索引;
- 字段 1 :条目类型
/Filter
:可选,表示是否压缩(如 FlateDecode)。
4. 传统 xref 与 流式 xref 对比
特性 | 传统 xref 表 | 流式 xref 表 |
---|---|---|
存储形式 | 纯文本表格 | 二进制流对象 |
trailer | 独立关键字 trailer |
合并在流对象字典中 |
是否支持压缩 | 不支持 | 支持(FlateDecode 等) |
增量更新 | 支持(通过 /Prev ) |
更灵活,效率更高 |
引入版本 | PDF 1.0 | PDF 1.5 |
总结
- xref 表 是 PDF 文件的"索引目录",让解析器能快速找到对象。
- trailer 提供了文档的全局信息,尤其是
/Root
,决定了整个 PDF 的起点。 - 流式交叉引用表 是 PDF 1.5 引入的改进方案,它将 xref 与 trailer 合并,并支持压缩,适合大文件和网络环境。
理解 xref 与 trailer 的机制,不仅能帮助解析 PDF,还为实现 PDF 的修改、增量更新和优化打下基础。