【问题标题】:System.ObjectDisposedException: 'Cannot access a closed file.'System.ObjectDisposedException:“无法访问已关闭的文件。”
【发布时间】:2017-07-15 14:53:19
【问题描述】:

在过去一周左右的时间里,这个异常让我头疼,我一辈子都无法修复它。如果用户选择这样做,我正在使用 iTextSharp 合并 PDF 文件并在其上添加水印。

这是合并的代码:

private void CreateMergedPdf(object sender, DoWorkEventArgs e)
{
        using (FileStream stream = new FileStream(pdfname, FileMode.Create)) {

            Document pdfDoc = new Document(PageSize.A4);
            PdfCopy pdf = new PdfCopy(pdfDoc, stream);

            pdfDoc.Open();
            int i = 0;


            foreach (File_class newpdf in AddedPDFs)
            {
                (sender as BackgroundWorker).ReportProgress(i++);

                if (newpdf.toMerge)
                {
                    PdfReader reader = new PdfReader(newpdf.file_path);
                    pdf.AddDocument(reader); //<!> Exception here

                    this.Dispatcher.Invoke(() => progBtxt.Text = "Merging file #" + newpdf.file_id + "..."); //Dispatcher.Invoke since UI is on seperate thread

                    if (add_wtrmk)//This is called for every FILE
                    {
                        AddWatermark(reader, stream);
                    }
                }


            }
     }
 }

这是水印的代码:

 private void AddWatermark(PdfReader reader, FileStream stream)
    {
        using (PdfStamper pdfStamper = new PdfStamper(reader, stream))//This is called for every PAGE of the file
        {

            for (int pgIndex = 1; pgIndex <= reader.NumberOfPages; pgIndex++)
            {
                Rectangle pageRectangle = reader.GetPageSizeWithRotation(pgIndex);
                PdfContentByte pdfData; //Contains graphics and text content of page returned by pdfstamper


                if (this.Dispatcher.Invoke(() => dropdown.Text == "Under Content"))
                {
                    pdfData = pdfStamper.GetUnderContent(pgIndex);
                }
                else if (this.Dispatcher.Invoke(() => dropdown.Text == "Over Content"))
                {
                    pdfData = pdfStamper.GetOverContent(pgIndex);
                }
                else//Just in case

                {
                    MessageBox.Show("Something went wrong when adding the watermark");
                    return;
                }

                //Set font
                pdfData.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 40);

                //Create new graphics state and assign opacity
                PdfGState graphicsState = new PdfGState();
                graphicsState.FillOpacity = 0.25F;

                //Set graphics state to pdfcontentbyte
                pdfData.SetGState(graphicsState);

                //Color of watermark
                pdfData.SetColorFill(BaseColor.GRAY);

                pdfData.BeginText();

                //Show text as per position and rotation
                this.Dispatcher.Invoke(() => pdfData.ShowTextAligned(Element.ALIGN_CENTER, WtrmkTextbox.Text, pageRectangle.Width / 2, pageRectangle.Height / 2, 45));

                pdfData.EndText();

            }
        }
    }

错误出现在合并代码上,特别是“pdf.AddDocument(reader);”行但是只有当我尝试在多个文件上添加水印时才会出现此错误(只有一个文件可以完美运行)。

我在想要么是 过早地关闭了某些东西,要么 addWatermark() 确实 - 我已经尝试更改我们的 using 状态,但无济于事。我一定是错过了什么

【问题讨论】:

  • 我的猜测是PdfStamper 正在关闭流,当您在AddWatermark 中处理它时。添加第一页时它不会失败吗?就在您添加水印后的第二次?
  • 是的,没错
  • 好的,我建议删除PdfStamper using 语句只是为了测试理论。如果这样可以解决问题,那么只需重组代码,以便在整个流完成之前不会调用内部 dispose。
  • 没有弹出异常,但是创建的 PDF 已损坏/损坏。我将研究重构代码
  • 好的,我将必要的参数传递给 AddWatermark() 并添加了一个简单的 if 语句。现在一切正常 - 感谢您在我的问题上花费一些时间!

标签: c# wpf itext


【解决方案1】:

好的,看来 PdfStamper 是罪魁祸首,我将必要的参数传递给 AddWatermark() 并添加了一个简单的 if 语句。现在一切正常。

非常感谢Mark Rucker

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多