C# 中的 IText 7 锁定错误 pdf

IText 7 in C# locking bad pdf

我 运行 遇到一个问题,我正在使用 IText 7 检查用户从 Internet 下载的 PDF。

对于我的测试用例,我创建了一个包含垃圾的文本文件并将其另存为 pdf。我知道它无效。

在代码中,我尝试使用 PDFReader 打开 PDF。

抛出异常,这是预料之中的。 调试代码时,Reader 对象到达 finally 点时为 null。所以 reader.close() 甚至没有开火。 我什至将文件复制到一个临时目录,以确保没有其他文件保存该文件。

异常发生后,我无法通过代码或在文件资源管理器中手动删除 PDF 文件。 这是我的一些代码。除了 Reader 部分,我删除了所有内容。此外,这段代码是在我尝试了一些事情之后,所以你看到我尝试将文件复制到临时文件。我试图在最后部分删除临时文件。那是在损坏的文件上失败。

以下是尝试验证错误 PDF 时抛出的两个异常。第一个来自 PDFReader 调用。

2021-04-09 13:18:11,079 ERROR GUI.Form1 - PDF header not found.
iText.IO.IOException: PDF header not found. at
iText.IO.Source.PdfTokenizer.GetHeaderOffset() at
iText.Kernel.Pdf.PdfReader.GetOffsetTokeniser(IRandomAccessSource> byteSource) at
iText.Kernel.Pdf.PdfReader..ctor(String filename, ReaderProperties properties) at
iText.Kernel.Pdf.PdfReader..ctor(FileInfo file) at
GUI.Form1.validatePDF(FileInfo pdfFile, HashSet`1 tmpMd5s)

第二个是尝试删除临时文件

2021-04-09 13:18:11,116 ERROR GUI.Form1 - The process cannot access the file
'C:\Users\ret63\AppData\Local\Temp\tmp27DE.tmp' because it is being used by another process.
System.IO.IOException: The process cannot access the file 'C:\Users\ret63\AppData\Local\Temp\tmp27DE.tmp' because it is being used by another process. at
System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.FileInfo.Delete() at
GUI.Form1.validatePDF(FileInfo pdfFile, HashSet`1 tmpMd5s)

PdfDocument pdfDoc = null;
PdfReader reader = null;

try
{
    using (reader = new PdfReader(testFile))
    {
        //pdfDoc = new PdfDocument(reader);
        //pdfDoc = new PdfDocument(new PdfReader(pdfFile.FullName));
        //Console.WriteLine("Number of Pages: " + pdfDoc.GetNumberOfPages());
        //pdfDoc.Close();
    }
}
catch(Exception ex)
{
    log.Error(ex.Message, ex);
    throw new Exception("Invalid PDF File: " + pdfFile.Name);
}
finally
{
    if (reader != null)
    {
        reader.Close();
    }
    if (pdfDoc != null && !pdfDoc.IsClosed())
    {
        pdfDoc.Close();
    }

    try
    {
        if (testFile.Exists)
        {
            testFile.Delete();
        }
    }
    catch (Exception ee)
    {
        Console.WriteLine(ee.Message);
    }
}

看起来像一个 iText 错误。如果您追踪 PdfReader 构造函数调用的内容,您会看到它 creates a FileStream that is conditionally locked. The FileStream gets wrapped in a RandomAccessSource which is then wrapped in a PdfTokenizer in GetOffsetTokeniser。如果 GetHeaderOffset 在第 1433 行抛出,则 tok 本地永远不会关闭。