PDF文件如何在下载时部分显示?
How are PDF files able to be partially displayed while downloading?
根据 PDF 1.7 specification,第 90 页,第 3.4 节:
The preceding sections describe the syntax of individual objects. This
section describes how objects are organized in a PDF file for efficient
random access and incremental update. A canonical PDF file initially
consists of four elements (see Figure 3.2):
A one-line header identifying the version of the PDF specification to which
the file conforms
A body containing the objects that make up the document contained in the
file
A cross-reference table containing information about the indirect
objects in the file
A trailer giving the location of the cross-reference table and of certain
special objects within the body of the file
基本上,结构有 header,然后是 body 内容,然后是交叉引用 table,最后是给出外部参照位置的预告片 table。这里的关键部分是 trailer
和 xref
table 位于文件的 末尾 ,而 xref
table包含body内容的相关元数据(主要是10位字节偏移量)。
鉴于外部参照 table 本身位于 PDF 文件的末尾:
- 为什么我的浏览器 (Google Chrome) 能够在整个文件下载完成之前部分显示 PDF 文件(前一百页左右)?
查看我部分下载的 PDF 文件的屏幕截图:
OP 描述的 PDF 文件类型也称为 "web optimized"(营销术语)或 "linearized"(PDF 术语中的技术术语)。
需要注意的是,它只有在满足两个额外条件(在文件的线性化特征之上)时才有效:
- PDF 查看器需要能够处理这些类型的 PDF 并利用线性化功能。
- 提供线性化 PDF 的(远程)主机需要支持 "byte streaming".
如果服务器不支持byte-streaming或者PDF文件没有线性化,整个文件仍然需要完全下载才能显示任何页面。
OP引用的关于PDF文件结构的描述不适用于线性化PDF文件。它们的组织方式略有不同:
- 对 PDF object 的排序应用特殊规则("standard" PDF 可以以任意顺序包含 object)。
- PDF 文档需要包含一些称为 "hint tables" 的额外结构,以保证在其中进行高效导航(即使尚未完全下载)。
关于附加结构,线性化 PDF 包含其 object 两组:
第一组是文档目录,所有document-level object,所有object属于first-to-be-displayed页(不一定 "page 0"!)。 object 应按顺序编号。
第二组持有所有其他 objects。
这些组应由 两个 xref
table 部分索引。
- 第一组的
xref
部分紧跟在第一个间接 object 之后,非常接近文件的开头。
- 第二组的
xref
部分位于文件末尾(与标准 non-linearized PDF 一样)。
%PDF-1.x
header 行之后的第一个 object 应包含一个字典键,指示文件的 /Linearized
属性。
这个整体结构允许符合 reader 的人非常快速地学习 object 地址的完整列表,而不需要从头到尾下载完整的文件:
在下载完整文件之前,查看器可以非常快速地显示第一页。
用户可以单击缩略图页面预览(或文件目录中的 link)以跳转到第 445 页,紧接在第一页之后(s) 已经显示,然后查看者可以请求第 445 页所需的所有 object,方法是通过字节范围请求请求远程服务器传送这些 "out of order",以便查看者可以更快地显示此页面. (当用户乱序阅读页面时,完整文档的下载仍然会在后台继续...)
PDF"linearization"的技术细节可以在'normative'Adobe's original PDF 1.7 Specification[=的附录F中找到73=](约 11 兆字节 -- 这本身就是此类线性化 PDF 文件的一个示例!)
根据 PDF 1.7 specification,第 90 页,第 3.4 节:
The preceding sections describe the syntax of individual objects. This section describes how objects are organized in a PDF file for efficient random access and incremental update. A canonical PDF file initially consists of four elements (see Figure 3.2):
A one-line header identifying the version of the PDF specification to which the file conforms
A body containing the objects that make up the document contained in the file
A cross-reference table containing information about the indirect objects in the file
A trailer giving the location of the cross-reference table and of certain special objects within the body of the file
基本上,结构有 header,然后是 body 内容,然后是交叉引用 table,最后是给出外部参照位置的预告片 table。这里的关键部分是 trailer
和 xref
table 位于文件的 末尾 ,而 xref
table包含body内容的相关元数据(主要是10位字节偏移量)。
鉴于外部参照 table 本身位于 PDF 文件的末尾:
- 为什么我的浏览器 (Google Chrome) 能够在整个文件下载完成之前部分显示 PDF 文件(前一百页左右)?
查看我部分下载的 PDF 文件的屏幕截图:
OP 描述的 PDF 文件类型也称为 "web optimized"(营销术语)或 "linearized"(PDF 术语中的技术术语)。
需要注意的是,它只有在满足两个额外条件(在文件的线性化特征之上)时才有效:
- PDF 查看器需要能够处理这些类型的 PDF 并利用线性化功能。
- 提供线性化 PDF 的(远程)主机需要支持 "byte streaming".
如果服务器不支持byte-streaming或者PDF文件没有线性化,整个文件仍然需要完全下载才能显示任何页面。
OP引用的关于PDF文件结构的描述不适用于线性化PDF文件。它们的组织方式略有不同:
- 对 PDF object 的排序应用特殊规则("standard" PDF 可以以任意顺序包含 object)。
- PDF 文档需要包含一些称为 "hint tables" 的额外结构,以保证在其中进行高效导航(即使尚未完全下载)。
关于附加结构,线性化 PDF 包含其 object 两组:
第一组是文档目录,所有document-level object,所有object属于first-to-be-displayed页(不一定 "page 0"!)。 object 应按顺序编号。
第二组持有所有其他 objects。
这些组应由 两个 xref
table 部分索引。
- 第一组的
xref
部分紧跟在第一个间接 object 之后,非常接近文件的开头。 - 第二组的
xref
部分位于文件末尾(与标准 non-linearized PDF 一样)。
%PDF-1.x
header 行之后的第一个 object 应包含一个字典键,指示文件的 /Linearized
属性。
这个整体结构允许符合 reader 的人非常快速地学习 object 地址的完整列表,而不需要从头到尾下载完整的文件:
在下载完整文件之前,查看器可以非常快速地显示第一页。
用户可以单击缩略图页面预览(或文件目录中的 link)以跳转到第 445 页,紧接在第一页之后(s) 已经显示,然后查看者可以请求第 445 页所需的所有 object,方法是通过字节范围请求请求远程服务器传送这些 "out of order",以便查看者可以更快地显示此页面. (当用户乱序阅读页面时,完整文档的下载仍然会在后台继续...)
PDF"linearization"的技术细节可以在'normative'Adobe's original PDF 1.7 Specification[=的附录F中找到73=](约 11 兆字节 -- 这本身就是此类线性化 PDF 文件的一个示例!)