PDFACompliance sometimes keeping files locked after disposal

,

Product: PDFTron

Product Version: 9.4

Please give a brief summary of your issue:
(Think of this as an email subject)

Hi,

Recently some code in an API which uses PDFNet have been raising this exception:

System.IO.IOException: The process cannot access the file ‘C:\local\Temp\tmpD854.tmp’ because it is being used by another process.
at System.IO.FileSystem.DeleteFile (System.IO.FileSystem, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)
at Inz.Adept.PdfFlattener.Api.Services.PdfFlattenService.PdfFlattenService.Archive (Inz.Adept.PdfFlattener.Api, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: D:\a\1\s\Inz.Adept.PdfFlattener.Api\Services\PdfFlattenService\PdfFlattenService.cs:127)

According to the stack trace, the exception is being raised by the following code in the place I have indicated:

public Stream Archive(Stream input)
{
logger.LogInformation(“Generating PDF/A archive (licenced = {licenced})”, this.licenced);

        using (input)
        {

            FileStream temp = new FileStream(Path.GetTempFileName(), FileMode.Open, FileAccess.Write, FileShare.ReadWrite);

            try 
            {                 
                input.CopyTo(temp);
                temp.Flush();

                using (PDFACompliance compliance = new PDFACompliance(true, temp.Name, null, PDFACompliance.Conformance.e_Level2B, null, 10, false))
                {
                    logger.LogDebug("PDF deserialized and converted to PDF/A 2B spec");
                    for (int i = 0; i < compliance.GetErrorCount(); i++)
                        logger.LogDebug("Error during archiving: {Error} ({Message})", compliance.GetError(i), PDFACompliance.GetPDFAErrorMessage(compliance.GetError(i)));

                    MemoryStream output = this.streams.GetRecyclableMemoryStream("Archive", this.configuration.Value.OutputStreamInitialBuffer);

                    compliance.SaveAs(output, true);

                    logger.LogDebug("PDF/A object persisted to memory stream, length {Length} bytes", output.Length);

                    output.Seek(0, SeekOrigin.Begin);

                    return output;
                }
            }
            finally
            {
                temp.Dispose();
                File.Delete(temp.Name);  // !!!!! Exception raised here
            }
        }
    }

It seems that the PDFACompliance object has locked the temp file preventing it from being deleted, and the lock is still being held even though PDFACompliance is being disposed.

Please note that this is an intermittent issue. Most calls to the above code are succeeding, only a small minority are raising the IOException.

Best regards,

Peter

Hello,

Thank you for contacting us about this. Are you able to pass in a byte[] array of the PDF to the PDFACompliance method instead of a temp path? This might be easier for your use case, as you are saving the document in memory as well. See API here for details.

I would prefer not to pass in large arrays, as they are likely to exceed 70k in size and cause large-object heap fragmentation. Passing in a memory stream would be ideal, but I see that the other PDFTron methods that accept streams simply allocate a byte array from the stream.

Hi @shakthi124 ,

I have also noticed that occasionally after calling PDFACompliance.SaveAs to save to a disk file, the file is locked and cannot be opened even after PDFACompliance has been disposed.