检测PDF文件是否正确(标题PDF)

我有一个Windows应用程序.NET管理许多PDF文件。 有些文件已损坏。

2个问题:我会用最糟糕的英语解释…对不起

1.)

如何检测pdf文件是否正确?

我想读PDF的标题和检测是正确的。

var okPDF = PDFCorrect(@“C:\ temp \ pdfile1.pdf”);

2.)

如何知道文件的byte [](bytearray)是否是PDF文件。

例如,对于ZIP文件,您可以检查前四个字节并查看它们是否与本地标头签名匹配,即以hex表示

50 4b 03 04

if(buffer [0] == 0x50 && buffer [1] == 0x4b && buffer [2] == 0x03 && buffer [3] == 0x04)

如果要将其加载到long中,则为(0x04034b50)。 作者:David Pierson

我希望PDF文件也一样。

byte [] dataPDF = …

var okPDF = PDFCorrect(dataPDF);

.NET中的任何示例源代码?

1)遗憾的是,没有简单的方法来确定pdf文件是否已损坏。 通常问题文件具有正确的标题,因此腐败的真正原因是不同的。 PDF文件实际上是PDF对象的转储。 该文件包含一个引用表,提供从文件开头的每个对象的确切字节偏移位置。 因此,大多数可能已损坏的文件具有损坏的偏移或可能是某些对象被遗漏。

确定文件已损坏的最佳方法是使用专用的PDF库。 这些.NET的免费版和商业版都有很多。 您可以尝试使用其中一个库加载PDF文件。 iTextSharp将是一个不错的选择。

2)根据PDF参考,PDF文件的标题通常形成%PDF-1.X(其中X是数字,目前从0到7)。 99%的PDF文件都有这样的标题。 但是还有一些其他类型的标题,Acrobat Viewer接受,甚至没有标题也不是PDF查看器的真正问题。 因此,如果文件没有标题,则不应将文件视为已损坏。 例如,标题可能出现在文件的前1024个字节内的某个位置,或者格式为%!PS-Adobe-Nn PDF-Mm

仅供参考,我是Docotic PDF库的开发人员。

我检查Header PDF是这样的:

public bool IsPDFHeader(string fileName) { byte[] buffer = null; FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read); BinaryReader br = new BinaryReader(fs); long numBytes = new FileInfo(fileName).Length; //buffer = br.ReadBytes((int)numBytes); buffer = br.ReadBytes(5); var enc = new ASCIIEncoding(); var header = enc.GetString(buffer); //%PDF−1.0 // If you are loading it into a long, this is (0x04034b50). if (buffer[0] == 0x25 && buffer[1] == 0x50 && buffer[2] == 0x44 && buffer[3] == 0x46) { return header.StartsWith("%PDF-"); } return false; } 

PDF文件的第一行是标识文件符合%PDF-1.0%PDF-1.1%PDF-1.2%PDF-1.3%PDF-1.4等的PDF规范版本的标题。

您可以通过从文件开头读取一些字节来检查这一点,看看您是否在开头有标题作为PDF文件进行匹配。 有关详细信息,请参阅Adobe的PDF参考 。

没有你的.NET示例(现在几年没有触及过这个问题),但即使我有,我也不确定你是否可以检查文件的完整有效内容。 标题可能没问题,但文件的其余部分可能搞砸了(正如你自己说的,有些文件已损坏)。

表现良好的PDF从前9个字节开始,以%PDF-1.x加上换行符(其中x在0..8中)。 1.x应该为您提供PDF文件格式的版本。 第二行是一些二进制字节,以帮助应用程序(编辑者)将PDF识别为非ASCII文本文件类型。

但是,你完全不能相信这个标签。 有很多应用程序使用PDF-1.7中的function,但声称是PDF-1.4,因此误导了一些观众吐出无效的错误消息。 (最像这些PDF是由于文件从较高版本到较低版本的错误管理转换而导致的。)

在PDF中没有这样的部分作为“标题”(也许最初的9字节%PDF-1.x是你用“标题”的意思?)。 可能嵌入了一个用于在PDF中保存元数据的结构,为您提供有关Author,CreationDate,ModDate,Title和其他一些内容的信息。

我可靠地检查PDF损坏的方法

没有其他方法可以检查PDF的有效性和未损坏程度,而不是渲染它。

对我个人来说,检查这种有效性的“便宜”且相当可靠的方法是使用Ghostscript 。

但是:您希望快速自动地实现此目的。 并且您希望以编程方式或通过脚本方法使用该方法来检查许多PDF。

这是诀窍:

  • 不要让Ghostscript将文件渲染到显示器或真实(图像)文件。
  • 请改用Ghostscript的nullpage设备。

这是一个示例命令行:

 gswin32c.exe ^ -o nul ^ -sDEVICE=nullpage ^ -r36x36 ^ "c:/path to /input.pdf" 

此示例适用于Windows; 在Unix上使用gs而不是gswin32c.exe-o /dev/null

使用-o nul -sDEVICE=nullpage将不会输出任何渲染结果。 但是Ghostscript处理input.pdf的所有stderr和stdout输出仍会出现在你的控制台中。 -r36x36将分辨率设置为36 dpi以加快检查速度。

对于未损坏的文件, %errorlevel% (或Linux上的$? )将为0 。 对于损坏的文件,它将为0 。 并且stdout上出现的任何警告或错误消息都可以帮助您识别input.pdf的问题。

没有其他方法来检查PDF文件的损坏,而不是以某种方式呈现它…

您可以使用iTextSharp打开并尝试解析文件(例如尝试并从中提取文本),但这可能有点过分。 除非您购买商业许可证,否则您还应该知道它是GNU Affero GPL 。

检查标题很棘手。 上面的一些代码根本不起作用,因为并非所有PDF都以%PDF开头。 在查看器中正确打开的一些pdf以BOM标记开头,其他的开头就像这样

———— e56a47d13b73819f84d36ee6a94183 Content-Disposition:form-data; name =“par”……等等

因此检查“%PDF”将不起作用。

我所做的是:

1.Validate扩展

2.打开PDF文件,读取标题(第一行)并检查它是否包含此字符串:“%PDF-”

3.通过搜索多个“/ Page”来检查文件是否包含指定页数的字符串(PDF文件应始终至少有1页)

如前所述,您还可以使用库来读取文件: 使用iTextSharp读取PDF文件