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

时间:2010-06-24 08:10:25

标签: c# file pdf header corrupt

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

2个问题:我会尝试用不完美的英语解释...抱歉

1)

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

我想阅读PDF的标题并检测它是否正确。

  

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

2)。

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

例如,对于ZIP文件,您可以检查前四个字节并查看它们是否与本地标题签名匹配,即以十六进制格式

  

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中的任何示例源代码?

7 个答案:

答案 0 :(得分:32)

我像这样检查标题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;

    }

答案 1 :(得分:18)

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-N.n PDF-M.m

仅供参考,我是Docotic PDF library的开发者。

答案 2 :(得分:8)

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

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

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

答案 3 :(得分:7)

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

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

在PDF中没有像“标题”那样的部分(也许%PDF-1.x的初始9字节是你用“标题”的意思?)。可能嵌入了一个用于在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文件的损坏,而不是以某种方式呈现它......


更新:同时不仅%PDF-1.0,%PDF-1.1,%PDF-1.2,%PDF-1.3,%PDF-1.4,%PDF-1.5,%PDF-1.6, %PDF-1.7和%PDF-1.8是有效的版本指标, ,但也是%PDF-2.0。

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

------------ e56a47d13b73819f84d36ee6a94183 内容处理:表格数据; NAME = “相提并论” ...等

因此检查“%PDF”将无效。

答案 6 :(得分:0)

我的工作是:

1.Validate extension

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

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

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