说明:

在PDF学习一 Hello World中简单提到了PDF文件结构。本文将重点讲PDF文件结构,指的是其文件物理组织方式,决定对象是如何存放在一个PDF文件中, 它们是如何被访问的,如何被更新的。

目标:

掌握PDF基本物理结构。

PDF文件格式包含以下4个部分:

文件头 Header

——指明了该文件所遵从的PDF规范的版本号,它出现在PDF文件的第一行。

%PDF−1.7

这是个固定格式,表示这个PDF文件遵循的PDF规范版本。从1.4版本以后,PDF文件的版本并不唯一的只是在这里表示了,可能后面会改写(catalog的Version词条),所以解析PDF的时候,如果这里的版本大于等于1.4,应该再比较一下catalog里面的version,取其中高一点的版本。

文件体 Body

——又称对象集合,PDF文件最重要的部分,文件中用到的所有对象,包括文本/图象/音乐/视频/字体/超连接/加密信息/文档结构信息等等,都在这里定义。

格式如下:

2 0 obj     
... 
end obj

一个对象的定义包含4个部分:

前面的2是对象序号,其用来唯一标记一个对象。0是生成号,按照PDF规范,如果一个PDF文件被修改,那这个数字是累加的,它和对象序号一起标记是原始对象还是修改后的对象,但是实际应用开发中,很少有用这种方式修改PDF的,都是重新编排对象号。obj和endobj是对象的定义范围,可以抽象的理解为这就是一个左括号和右括号;省略号部分是PDF规定的任意合法对象(一共8种)。

可以通过R关键字来引用任何一个对象,比如要引用上面的对象,可以使用2 0 R。

交叉引用表 Cross-reference table

——为了能对间接对象进行随机存取而设立的一个间接对象的地址索引表。(实际以偏移+索引的方式储存对象地址)

普通文件交叉引用表

xref                             % 表示交叉引用表开始
0 5                              % 0表示交叉引用表描述的对象编号从0开始,5表示共有5个对象
0000000000 65535 f  % 一般pdf都是以这行开始交叉引用表,起始地址0和最大产生号65535,f 表示释放
0000000017 00000 n % 对象号为1的偏移地址,产生号0,n表示在使用中
0000000081 00000 n % 对象号为2的偏移地址,产生号0,n表示在使用中,其他类同
0000000331 00000 n
0000000409 00000 n

增量更新的交叉引用表

xref
0 1
0000000000 65535 f
3 1                              % 对象编号从3开始,1表示共有1个对象
0000025325 00000 n % 对象号为3的偏移地址,产生号0,n表示在使用中
23 2
0000025518 00002 n % 对象号为23的偏移地址,产生号为2表示被删除过,又重新开始使用,n表示在使用中
0000025635 00000 n
30 1
0000025777 00000 n

文件尾 Trailer

——声明了交叉引用表的地址,即指明了文件体的根对象(Catalog),从而能够找到PDF文件中各个对象体的位置,达到随机访问。另外还保存了PDF文件的加密等安全信息。

trailer              % 文件尾标识,是小写t
<</Info 1 0 R  % 文件信息字典,包含Title、Author、Subject、Keywords等信息

/Root 2 0 R    % 指向文件体的根对象(Catalog)

/Size 20>>     % 文件中对象总数为20
startxref 
2559              % 交叉引用表偏移地址
%%EOF        % 文件结束标识

增量更新

1)PDF文件内容可以增量更新无需重写整篇文件。变化数据被附加到文件尾段,保持原内容不变。用这种方法更新文件最大的优势是一个篇幅很大的文件做小改动可以快速保存。

2)文件更新时新增的交叉引用表部分仅包含那些已经被修改,替换,或删掉的对象。删除掉的对象原封不动的留在文件中,对应的交叉引用表项被标记为已删除。新增的文件尾包括所有的选项(可能是改进过的)包括之前的文件尾部分,Prev项给出之前交叉引用部分的位置。一篇被更新过多次的文件包含了多个文件尾;每个文件尾都有自己的结束标识(%%EOF)。

3)由于更新的部分被添加到文件中,一个文件可能有一个相同对象的多个副本,而保持相同的对象标识(对象编号和生成编号)。在以下情况这个现象就会发生,例如,如果一个文本标注被修改多次并且文件保存了多次的修改。因为文本标注对象没删除,它仍保持着之前相同的对象号和生成号。但一个被修改过的对象副本会被包含在更新部分添加到文件中。更新的交叉引用表部分包含这个新的对象的字节偏移值,覆盖原先交叉引用表中旧的字节偏移值。当一个用户应用程序(consumer application FoxitReader)读取文件时,它必需用这种方法构建它自己的交叉引用表信息,即文件中每个对象的最新副本是被访问的那一个。

PDF 1.4之后,版本号Version是可以在增量更新中修改。

后记:

PDF物理结构中还有Object Streams、Cross-Reference Streams,大家对哪个感兴趣可留言给我。

问题汇总:

Q: 一个PDF文件可以有多个文件尾吗?

A:是的。增量更新之后PDF文件会有多个文件体,多个交叉引用表,多个文件尾。

微信公众号

PDF学习二:PDF文件物理结构相关推荐

  1. PDF学习三 PDF文件逻辑结构

    说明: 要解析一个PDF文件,首先要掌握PDF的物理结构,这是第一步.但是这个仅仅只是基础,更重要的是对PDF逻辑结构的解析.PDF的逻辑大体上是一个树状结构,根节点是catalog字典,通过这里去解 ...

  2. Linux配置协同工作目录,Linux学习二:文件权限与目录配置

    Linux文件权限 ls指令可查看当前目录下的所有文件及文件夹,ls -al可以展示所有文件夹得详细属性. 其中,第一列为文件类型与权限 如图所示: 第一个字符代表这个文件是『目录.文件或链接文件等等 ...

  3. PDF杂谈一 PDF对象流

    引言 在"PDF学习二 PDF物理结构"的说明里用了较大的篇幅说明了交叉引用表,但是有人表示说,用记事本打开一个PDF文件,并没有看到所谓的交叉引用表. 精华提炼出来的文档的描述有 ...

  4. java入门123pdf二维码pdf_Java入门123:一个老鸟的Java学习心得 pdf

    资源名称:Java入门123:一个老鸟的Java学习心得 pdf 第1篇 Java语言基本语法 第1章 让自己的第一个Java程序跑起来 第2章 搭建自己的集成开发环境 第3章 Java中的基本数据类 ...

  5. linux环境编程 学习,学习linux环境高级编程首先学习的是文件的操作。因为有.pdf...

    学习linux环境高级编程首先学习的是文件的操作.因为有 学习 Linux 环境高级编程,首先学习的是文件的操作.因为有一句很有趣的话"Linux 下一切皆文件".所以掌握了文件操 ...

  6. 怎么把pdf转换成excel文件?

    怎么把pdf转换成excel文件?互联网时代的今天,许多办公技巧都有了翻天覆地的变化,其中尤以pdf.excel.word.图片几种文件的相互转换变化较多.过去的办公文员们无论是把pdf转换成exce ...

  7. 如何把PDF转成PPT文件?这几招简单方便

    很多工作者,经常在会议中会用到PPT来汇总方案,但是有些优质的文案是放在PDF文件中储存的,没有办法很好的呈现出来,这时就需要将PDF转成PPT文件,那PDF怎么转换为PPT文件简单方便呢?下面给大家 ...

  8. 怎么把PDF转换成CAD文件呢?分享两种转换小技巧

    PDF文件怎么把它转换成CAD文件呢?做CAD设计的小伙伴是不是经常会收到甲方发来的PDF格式的CAD文件?他们会觉得PDF格式好发送,容易打开,但我们作为专业编辑.绘制CAD图纸人员,是要对文件进行 ...

  9. IntelliJ IDEA 14,15 使用教程,实战总结,倾囊相授,内附PDF学习文档

    转载博文,尊重原创,感谢前辈分享,原文地址:"请叫我大师兄__"的CSDN博客主页 文章目录 前言 一.安装 二.使用 1.Debug 2.修改内存 3.一般设置 4.高级设置 5 ...

最新文章

  1. c 传入易语言字节,易语言字节集参数传递详解
  2. ASP.NET MVC 实现模式 - ModelBuilder
  3. 瑞士银行开户条件有哪些,瑞士银行开户的流程及注意事项是什么?
  4. Leetcode 292. Nim 游戏 解题思路及C++实现
  5. 计算机虚拟化技术论文,【计算机网络论文】虚拟技术计算机网络论文(共1775字)...
  6. PHP 数组函数分类和整理
  7. disp直接将内容输出在Matlab命令窗口中
  8. sql 插入多行数据的问题
  9. Tree UVA - 548(二叉树递归遍历)
  10. 图解 Android Handler 线程消息机制
  11. SiteMesh详解
  12. CentOS7.0系统安全加固实施方案
  13. PID控制电机输出作为电机PWM占空比输入的理解
  14. Excel表格中如何将文本型改为数值型数据
  15. 顺丰快递单号查询API开发指南-快递鸟
  16. 100 offer:为什么你不需要做一名全栈工程师?
  17. Xenu简单使用说明
  18. 中国杀软套路深:CIA怼遍全世界竟然干不过它
  19. MNIST手写数字识别之MLP实现
  20. 计算机一级题库及答案2019百度云,2018-2019-计算机一级考试题库和答案-优秀word参考范文-(6页)...

热门文章

  1. Myeclipse 10激活失败解决方案
  2. idea恢复默认快捷键
  3. 以旧焕新的css滤镜
  4. mysql索引的实现原理
  5. Python日志库logging、loguru、Eliot
  6. 二《计算机网络》-物理层部分
  7. 我是“阴谋论”支持者!
  8. js 正则判断字符串是否全为空格
  9. C++ lambda 表达式深剖
  10. echarts+bmap