Stefano Carta
Stefano Carta

Reputation: 1

ItextSharp System.ObjectDisposedException: 'Cannot access a closed file.'

I found this sample to edit a pdf...but I receive an exception on the line psStamp.Close() error: System.ObjectDisposedException: 'Cannot access a closed file.'

any idea?

Public Sub ReplacePDFText(ByVal strSearch As String, ByVal scCase As StringComparison, ByVal strSource As String, ByVal strDest As String)

    Dim psStamp As PdfStamper = Nothing 'PDF Stamper Object
    Dim pcbContent As PdfContentByte = Nothing 'Read PDF Content

    If File.Exists(strSource) Then 'Check If File Exists

        Dim pdfFileReader As New PdfReader(strSource) 'Read Our File

        psStamp = New PdfStamper(pdfFileReader, New FileStream(strDest, FileMode.Create)) 'Read Underlying Content of PDF File

        pbProgress.Value = 0 'Set Progressbar Minimum Value
        pbProgress.Maximum = pdfFileReader.NumberOfPages 'Set Progressbar Maximum Value

        For intCurrPage As Integer = 1 To pdfFileReader.NumberOfPages 'Loop Through All Pages

            Dim lteStrategy As LocTextExtraction.LocTextExtractionStrategy = New LocTextExtraction.LocTextExtractionStrategy 'Read PDF File Content Blocks

            pcbContent = psStamp.GetUnderContent(intCurrPage) 'Look At Current Block

            'Determine Spacing of Block To See If It Matches Our Search String
            lteStrategy.UndercontentCharacterSpacing = pcbContent.CharacterSpacing
            lteStrategy.UndercontentHorizontalScaling = pcbContent.HorizontalScaling

            'Trigger The Block Reading Process
            Dim currentText As String = PdfTextExtractor.GetTextFromPage(pdfFileReader, intCurrPage, lteStrategy)

            'Determine Match(es)
            Dim lstMatches As List(Of iTextSharp.text.Rectangle) = lteStrategy.GetTextLocations(strSearch, scCase)

            Dim pdLayer As PdfLayer 'Create New Layer
            pdLayer = New PdfLayer("Overrite", psStamp.Writer) 'Enable Overwriting Capabilities

            'Set Fill Colour Of Replacing Layer
            pcbContent.SetColorFill(BaseColor.RED)

            For Each rctRect As Rectangle In lstMatches 'Loop Through Each Match

                pcbContent.Rectangle(rctRect.Left, rctRect.Bottom, rctRect.Width, rctRect.Height) 'Create New Rectangle For Replacing Layer

                pcbContent.Fill() 'Fill With Colour Specified

                pcbContent.BeginLayer(pdLayer) 'Create Layer

                pcbContent.SetColorFill(BaseColor.BLACK) 'Fill aLyer

                pcbContent.Fill() 'Fill Underlying Content

                Dim pgState As PdfGState 'Create GState Object
                pgState = New PdfGState()

                pcbContent.SetGState(pgState) 'Set Current State

                pcbContent.SetColorFill(BaseColor.WHITE) 'Fill Letters

                pcbContent.BeginText() 'Start Text Replace Procedure

                pcbContent.SetTextMatrix(rctRect.Left, rctRect.Bottom) 'Get Text Location

                'Set New Font And Size
                pcbContent.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 9)

                pcbContent.ShowText("AMAZING!!!!") 'Replacing Text

                pcbContent.EndText() 'Stop Text Replace Procedure

                pcbContent.EndLayer() 'Stop Layer replace Procedure

            Next

            pbProgress.Value = pbProgress.Value + 1 'Increase Progressbar Value

            pdfFileReader.Close() 'Close File

        Next

        psStamp.Close() 'Close Stamp Object

    End If

    'Add Watermark
    'AddPDFWatermark("C:\test_words_replaced.pdf", "C:\test_Watermarked_and_Replaced.pdf", Application.StartupPath & "\Anuba.jpg")

End Sub

Upvotes: 0

Views: 86

Answers (1)

mkl
mkl

Reputation: 95963

The PdfStamper needs its underlying PdfReader until the end but you close it before that (actually even multiple times!):

Dim pdfFileReader As New PdfReader(strSource) 'Read Our File

psStamp = New PdfStamper(pdfFileReader, New FileStream(strDest, FileMode.Create)) 'Read Underlying Content of PDF File

...

For intCurrPage As Integer = 1 To pdfFileReader.NumberOfPages 'Loop Through All Pages

    ...

    pdfFileReader.Close() 'Close File

Next

psStamp.Close() 'Close Stamp Object

To fix this, don't close your PdfReader before your PdfStamper:

Dim pdfFileReader As New PdfReader(strSource) 'Read Our File

psStamp = New PdfStamper(pdfFileReader, New FileStream(strDest, FileMode.Create)) 'Read Underlying Content of PDF File

...

For intCurrPage As Integer = 1 To pdfFileReader.NumberOfPages 'Loop Through All Pages

    ...

    ' remove this: pdfFileReader.Close() 'Close File

Next

psStamp.Close() 'Close Stamp Object
pdfFileReader.Close() 'Close File

Upvotes: 1

Related Questions