itextsharp not closing files

情到浓时终转凉″ 提交于 2019-12-11 12:54:16

问题


I've got some code for itextsharp merging 2 pdf files. Found it online somewhere. The merging works fine, but it seems that the source files are staying in use after it is all done. What I'd like to do is to delete the first file that i have already merged, which is uploaded via a fileupload, and keep only the merged file. It's definitely the code doing the merging that is causing the file to stay open. I tried to delete the file on the server and it tells me something like it's open by the IIShelper. Through hours of work I narrowed to down to this stuff. Why is it keeping the file in use?

    public static void MergeFiles(string destinationFile, string[] sourceFiles)
    {

        int f = 0;
        // we create a reader for a certain document
        PdfReader reader = new PdfReader(sourceFiles[f]);
        // we retrieve the total number of pages
        int n = reader.NumberOfPages;
        // step 1: creation of a document-object
        Document document = new Document(reader.GetPageSizeWithRotation(1));
        // step 2: we create a writer that listens to the document
        PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create));
        // step 3: we open the document
        document.Open();
        PdfContentByte cb = writer.DirectContent;
        PdfImportedPage page;
        int rotation;
        if(reader.IsEncrypted() == false)
        {
            // step 4: we add content
            while (f < sourceFiles.Length)
            {
                int i = 0;
                while (i < n)
                {
                    i++;
                    document.SetPageSize(reader.GetPageSizeWithRotation(i));
                    document.NewPage();
                    page = writer.GetImportedPage(reader, i);
                    rotation = reader.GetPageRotation(i);
                    if (rotation == 90 || rotation == 270)
                    {
                        cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
                    }
                    else
                    {
                        cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
                    }
                }
                f++;
                if (f < sourceFiles.Length)
                {
                    reader = new PdfReader(sourceFiles[f]);
                    // we retrieve the total number of pages
                    n = reader.NumberOfPages;
                }

            }
        }
        else
        {
            //is encrypted
        }
        // step 5: we close the document
        document.Close();
        reader.Close();
        reader.Dispose();


    }

Thanks in advance


回答1:


You are only closing one reader at the end, but opening one reader per file. Thus, only the last reader will get closed.

You need to close the old reader before you do

    reader = new PdfReader(sourceFiles[f]);



回答2:


Ok, here is what I ended up with.

    public static void MergeFiles(string destinationFile, string[] sourceFiles)
    {

        int f = 0;
        // we create a reader for a certain document
        //PdfReader reader = new PdfReader(sourceFiles[f]);
        PdfReader reader = new PdfReader(new RandomAccessFileOrArray(sourceFiles[f], true), null);
        if (reader.IsEncrypted() == false)
        {
            // we retrieve the total number of pages
            int n = reader.NumberOfPages;
            // step 1: creation of a document-object
            Document document = new Document(reader.GetPageSizeWithRotation(1));
            // step 2: we create a writer that listens to the document
            using(var destinationFileStream = new FileStream(destinationFile, FileMode.Create))
            {
                PdfWriter writer = PdfWriter.GetInstance(document, destinationFileStream);
                // step 3: we open the document
                document.Open();
                PdfContentByte cb = writer.DirectContent;
                PdfImportedPage page;
                int rotation;

                    // step 4: we add content
                    while (f < sourceFiles.Length)
                    {
                        int i = 0;
                        while (i < n)
                        {
                            i++;
                            document.SetPageSize(reader.GetPageSizeWithRotation(i));
                            document.NewPage();
                            page = writer.GetImportedPage(reader, i);
                            rotation = reader.GetPageRotation(i);
                            if (rotation == 90 || rotation == 270)
                            {
                                cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
                            }
                            else
                            {
                                cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
                            }
                        }
                        f++;
                        if (f < sourceFiles.Length)
                        {

                            reader = new PdfReader(sourceFiles[f]);
                            // we retrieve the total number of pages
                            n = reader.NumberOfPages;
                        }

                    }
                    //close everything
                    document.Close();
                    reader.Close();
                    destinationFileStream.Close();
            }

        }
        else
        {
            //is encrypted
            reader.Close();
        }

    }

I tried every possible combination of closing the reader, etc.., but it would seem that no matter what itext kept source file open.

What did the trick was changing PdfReader reader = new PdfReader(sourceFiles[f]) to PdfReader reader = new PdfReader(new RandomAccessFileOrArray(sourceFiles[f], true), null).

The RandomAccessFileOrArray made the difference.

I'm not by any means an itextsharp expert. Can someone explain to me why exactly this has such a large effect on itext releasing files in this case?




回答3:


Here is what I did : I created a list of all readers of files I merge to keep track of them, then I closed them all in the end.

List<PdfReader> readers = new List<PdfReader>();
        try
        {
            int f = 0;

            //PdfReader reader = new PdfReader(sSrcFile[f]);

            readers.Add(new PdfReader(sSrcFile[f]));

            int n = readers[f].NumberOfPages;
            //Response.Write("There are " + n + " pages in the original file.\n");
            Document document = new Document(PageSize.A4);

            PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create));

            document.Open();
            PdfContentByte cb = writer.DirectContent;
            PdfImportedPage page;

            int rotation;
            while (f < sSrcFile.Length)
            {
                int i = 0;
                while (i < n)
                {
                    i++;

                    document.SetPageSize(PageSize.A4);
                    document.NewPage();
                    page = writer.GetImportedPage(readers[f], i);

                    rotation = readers[f].GetPageRotation(i);
                    if (rotation == 90 || rotation == 270)
                    {
                        cb.AddTemplate(page, 0, -1f, 1f, 0, 0, readers[f].GetPageSizeWithRotation(i).Height);
                    }
                    else
                    {
                        cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
                    }
                    //Response.Write("\n Processed page " + i + "\n");
                }

                f++;
                if (f < sSrcFile.Length)
                {
                    readers.Add(new PdfReader(sSrcFile[f]));
                    n = readers[f].NumberOfPages;
                    //Response.Write("ff : There are " + n + " pages in the original file.\n");
                }
            }

            //Response.Write(returnLocation);
            document.Close();

            for (var i = 0; i < readers.Count; i++)
            {
                readers[i].Close();
            }

            return returnLocation;
        }
        catch (Exception e)
        {
            Response.Write("The error message is: " + e.Message);
            return e.Message;
        }



回答4:


I had the same problem in VB.net. You need to close each reader, pdfDoc and writer.

Imports iTextSharp.text.pdf
Imports iTextSharp.text

Public Sub MergePDF_File(ByVal fileArray As String(), ByVal outPutPDF As String)

    If fileArray Is Nothing OrElse fileArray.Length = 0 Then
        Throw New ApplicationException("No file list")
    End If
    If String.IsNullOrEmpty(outPutPDF) Then
        Throw New ApplicationException("Must specify output file")
    End If

    Dim pdfDoc As iTextSharp.text.Document = Nothing
    Dim writer As iTextSharp.text.pdf.PdfCopy = Nothing

    For i = 0 To fileArray.Length - 1
        Using reader As New iTextSharp.text.pdf.PdfReader(fileArray(i))

            If i = 0 Then
                pdfDoc = New iTextSharp.text.Document(reader.GetPageSizeWithRotation(1))
                writer = New iTextSharp.text.pdf.PdfCopy(pdfDoc, _
                                      New FileStream(outPutPDF, _
                                      FileMode.OpenOrCreate, _
                                      FileAccess.Write))
                pdfDoc.Open()
            End If

            Dim pageCount As Integer = reader.NumberOfPages
            For pg = 1 To pageCount
                pdfDoc.SetPageSize(reader.GetPageSizeWithRotation(pg))
                pdfDoc.NewPage()
                Dim page As iTextSharp.text.pdf.PdfImportedPage = Nothing
                page = writer.GetImportedPage(reader, pg)
                writer.AddPage(page)
            Next

            reader.Close()
        End Using
    Next

    pdfDoc.Close()
    writer.Close()

End Sub



回答5:


One thing I noticed is that you are not closing out the FileStream object that you are constructing. Since the FileStream class implements IDisposable, I would highly recommend that you wrap the code in a using block so that the resources will be cleaned up appropriately.

    using(var destinationFileStream = new FileStream(destinationFile, FileMode.Create))
    {
        PdfWriter writer = PdfWriter.GetInstance(document, destinationFileStream));
        // step 3: we open the document
        document.Open();
        PdfContentByte cb = writer.DirectContent;
        PdfImportedPage page;
        int rotation;
        if(reader.IsEncrypted() == false)
        {
            // step 4: we add content
            while (f < sourceFiles.Length)
            {
                int i = 0;
                while (i < n)
                {
                    i++;
                    document.SetPageSize(reader.GetPageSizeWithRotation(i));
                document.NewPage();
                page = writer.GetImportedPage(reader, i);
                rotation = reader.GetPageRotation(i);
                if (rotation == 90 || rotation == 270)
                {
                    cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
                }
                else
                {
                    cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
                }
            }
            f++;
            if (f < sourceFiles.Length)
            {
                reader = new PdfReader(sourceFiles[f]);
                // we retrieve the total number of pages
                n = reader.NumberOfPages;
            }

        }
    }
    else
    {
        //is encrypted
    }
 }


来源:https://stackoverflow.com/questions/20574993/itextsharp-not-closing-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!