ItextSharp报错System.ObjectDisposedException:无法访问已关闭文件求解决
解决PDF编辑代码中System.ObjectDisposedException异常的问题
错误原因
- 你在遍历PDF页面的For循环内部调用了
pdfFileReader.Close(),第一次循环就关闭了PdfReader实例。但PdfStamper是基于这个Reader创建的,后续循环的页面操作、以及最后执行psStamp.Close()时,都需要Reader处于可用状态,提前关闭会导致资源已被释放的异常。
修复步骤
- 移除循环内的
pdfFileReader.Close(),将其移到psStamp.Close()之后执行,确保Stamper完成所有操作后再关闭Reader。 - 推荐使用Using语句(VB.NET的Using会自动处理资源释放),避免手动管理关闭顺序出错的问题,同时提升代码健壮性。
修正后的代码
Public Sub ReplacePDFText(ByVal strSearch As String, ByVal scCase As StringComparison, ByVal strSource As String, ByVal strDest As String) Dim psStamp As PdfStamper = Nothing Dim pcbContent As PdfContentByte = Nothing If File.Exists(strSource) Then ' 使用Using自动管理PdfReader和FileStream的资源释放 Using pdfFileReader As New PdfReader(strSource) Using destStream As New FileStream(strDest, FileMode.Create) psStamp = New PdfStamper(pdfFileReader, destStream) pbProgress.Value = 0 pbProgress.Maximum = pdfFileReader.NumberOfPages For intCurrPage As Integer = 1 To pdfFileReader.NumberOfPages Dim lteStrategy As New LocTextExtraction.LocTextExtractionStrategy pcbContent = psStamp.GetUnderContent(intCurrPage) lteStrategy.UndercontentCharacterSpacing = pcbContent.CharacterSpacing lteStrategy.UndercontentHorizontalScaling = pcbContent.HorizontalScaling Dim currentText As String = PdfTextExtractor.GetTextFromPage(pdfFileReader, intCurrPage, lteStrategy) Dim lstMatches As List(Of iTextSharp.text.Rectangle) = lteStrategy.GetTextLocations(strSearch, scCase) Dim pdLayer As New PdfLayer("Overrite", psStamp.Writer) pcbContent.SetColorFill(BaseColor.RED) For Each rctRect As Rectangle In lstMatches pcbContent.Rectangle(rctRect.Left, rctRect.Bottom, rctRect.Width, rctRect.Height) pcbContent.Fill() pcbContent.BeginLayer(pdLayer) pcbContent.SetColorFill(BaseColor.BLACK) pcbContent.Fill() Dim pgState As New PdfGState() pcbContent.SetGState(pgState) pcbContent.SetColorFill(BaseColor.WHITE) pcbContent.BeginText() pcbContent.SetTextMatrix(rctRect.Left, rctRect.Bottom) pcbContent.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 9) pcbContent.ShowText("AMAZING!!!!") pcbContent.EndText() pcbContent.EndLayer() Next pbProgress.Value = pbProgress.Value + 1 Next psStamp.Close() End Using End Using End If 'Add Watermark 'AddPDFWatermark("C:\test_words_replaced.pdf", "C:\test_Watermarked_and_Replaced.pdf", Application.StartupPath & "\Anuba.jpg") End Sub
额外说明
- 使用Using语句包裹PdfReader和FileStream,会在代码块结束时自动调用Dispose方法释放资源,无需手动调用Close,避免了资源管理顺序错误的问题。
- 如果坚持手动管理资源,必须确保关闭顺序:先关闭PdfStamper,再关闭PdfReader,最后关闭FileStream。
内容的提问来源于stack exchange,提问作者Stefano Carta
相关产品推荐
相关产品推荐

