我有一个 PDF 文件,我的阅读器 (Zathura) 无法打开它。我有另一个阅读器 (mupdf) 可以打开它。我相信 Zathura 依赖于检测文件魔法值(前几个字节),因为它可以打开 PDF 以外的其他格式。
经检查,我注意到它被检测为Java serialisation data, version 5
。
$ file document.pdf
document.pdf: Java serialization data, version 5
检查前几个字节:
00000000: aced 0005 7572 0002 5b42 acf3 17f8 0608 ....ur..[B......
00000010: 54e0 0200 0078 7000 0389 9525 5044 462d T....xp....%PDF-
%PDF
通常,PDF从字节 0开始。
如果我去掉前 27 个字节,我就可以打开该文件:
$ dd if=~/Downloads/file.pdf skip=27 bs=1 of=/tmp/file.pdf
进一步检查显示该文件是由 Apache FOP 版本 1.1 生成的。尽管在 Google 上搜索了很多,但我还是找不到任何关于此格式 PDF 的提及。
这是 PDF 的有效格式吗?
更新深入研究一下标题后,它确实是一个 Java 序列化数组,其中“数组”包含 PDF 文件数据。我查看了规格对于序列化协议,特别是语法描述 从中我可以将 27 字节标头解码为:
AC ED
=STREAM_MAGIC
将文件的内容标识为序列化协议。00 05
=STREAM_VERSION
序列化版本。75
=TC_ARRAY
72
=TC_CLASSDESC
00 02
= 类名的长度。5b 42
= 班级名称ur
AC F3 17 F8 06 08 54 E0
=SerialVersionUID
,类的序列版本标识符。02
= 标志SC_SERIALIZABLE
- 该对象支持序列化。00 00
= 此类中的字段数(零!)78
=TC_ENDBLOCKDATA
。70
=TC_NULL
(对象没有父类)。00 03 89 95
=“数组”的长度 = 231829 = 数据大小(以字节为单位)
提取的 PDF 确实长 231829 字节
$ dd if=document.pdf skip=27 bs=1 | wc -c
231829 bytes
这表明文件没有损坏,确实是包含 PDF 文档的 Java 序列化数组。但这会被视为有效的 PDF 吗?
答案1
这参考有话要说:
3.4.1 File Header
The first line of a PDF file is a header identifying the version of the PDF
specification to which the file conforms. For a file conforming to PDF 1.7,
the header should be
%PDF−1.7
我对这句话的解释是,严格来说,你拥有的文件是不是有效的 PDF 文件。第一行结束具有正确的值,但其前面包含额外的“垃圾”。
话虽如此,如何寻找魔法很可能取决于 PDF 阅读器的实现%PDF-x.x
,而我的猜测是,大多数人会一直阅读直到他们碰到第一个,0D 0A
而在您的情况下,它恰好位于 PDF 标记之后。
如果序列化数据包含该0D 0A
值,那么我猜测 mupdf 也无法读取它。