Me encuentro con un problema en el que estoy usando IText 7 para verificar un PDF que un usuario ha descargado de Internet.
Para mi caso de prueba, creé un archivo de texto con basura y lo guardé como pdf. Sé que no es válido.
En el código, intento abrir el PDF usando PDFReader.
Se está lanzando una excepción, esto es lo esperado. Al depurar el código, el objeto Reader es nulo cuando llega al lugar final. Así que el lector.close() ni siquiera está disparando. Incluso estoy copiando el archivo en un directorio temporal solo para asegurarme de que nada más contenga el archivo.
Entonces no puedo eliminar el archivo PDF ni en código ni manualmente en un explorador de archivos después de la excepción. Aquí hay algo de mi código. Eliminé todo menos la parte del Lector. Además, este código es después de haber intentado algunas cosas, por lo que está viendo mi intento de copiar el archivo en un archivo temporal. Intenté eliminar el archivo temporal en la parte final. Eso está fallando en un archivo corrupto.
Estas son las dos excepciones que se lanzan al intentar validar un PDF incorrecto. El primero es de la llamada PDFReader.
2021-04-09 13:18:11,079 ERROR GUI.Form1 - No se encontró el encabezado del PDF.
iText.IO.IOException: encabezado PDF no encontrado. en
iText.IO.Source.PdfTokenizer.GetHeaderOffset() en
iText.Kernel.Pdf.PdfReader.GetOffsetTokeniser(IRandomAccessSource> byteSource) en
iText.Kernel.Pdf.PdfReader..ctor (nombre de archivo de cadena, propiedades de ReaderProperties) en
iText.Kernel.Pdf.PdfReader..ctor (archivo FileInfo) en
GUI.Form1.validatePDF(FileInfo pdfFile, HashSet`1 tmpMd5s)
El segundo es del intento de eliminar el archivo temporal.
2021-04-09 13:18:11,116 ERROR GUI.Form1 - El proceso no puede acceder al archivo
'C:\Users\ret63\AppData\Local\Temp\tmp27DE.tmp' porque está siendo utilizado por otro proceso.
System.IO.IOException: el proceso no puede acceder al archivo 'C:\Users\ret63\AppData\Local\Temp\tmp27DE.tmp' porque otro proceso lo está utilizando. en
System.IO.__Error.WinIOError(Int32 errorCode, String mayFullPath) en System.IO.FileInfo.Delete() en
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); } }Parece un error de iText. Si rastrea lo que llama el constructor de PdfReader , verá que crea un FileStream que está bloqueado condicionalmente. El FileStream se envuelve en un RandomAccessSource que luego se envuelve en un PdfTokenizer en GetOffsetTokeniser . Si GetHeaderOffset lanza en la línea 1433, ese tok local nunca se cierra.