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
本地永远不会关闭。
我 运行 遇到一个问题,我正在使用 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
本地永远不会关闭。