ITextSharp - 使用PdfStamper导致MemoryStream关闭

时间:2015-08-17 10:46:06

标签: c# pdf itextsharp memorystream

我正在使用ITextSharp将多页PDF文件拆分为单页文件。我还设法使用MemoryStream将这些单页PDF添加到zip文件中。

现在,在将这些PDF添加到zip文件之前,我需要使用PdfStamper为这些PDF添加密码保护。但每当我尝试这个时,就会抛出一个ObjectDisposedException - Cannot access a closed Stream.

Ionic.Zip.ZipFile zipFile = new Ionic.Zip.ZipFile();

        int cnt = 0;
        try
        {
            iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(new iTextSharp.text.pdf.RandomAccessFileOrArray(sourcePdfPath), new ASCIIEncoding().GetBytes(""));

            for (cnt = 1; cnt <= reader.NumberOfPages; cnt++)
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (iTextSharp.text.Document document = new iTextSharp.text.Document())
                    {
                        iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(document, memoryStream);

                        using (PdfStamper stamper = new PdfStamper(reader, memoryStream))
                        {
                            stamper.SetEncryption(
                                null,
                                Encoding.ASCII.GetBytes("password_here"),
                                PdfWriter.ALLOW_PRINTING,
                                PdfWriter.ENCRYPTION_AES_128);
                        }

                        memoryStreamForZipFile = new MemoryStream(memoryStream.ToArray());
                        memoryStreamForZipFile.Seek(0, SeekOrigin.Begin);
                    }
                }
            }

            zipFile.Save(destinationFolder + "/" + fileName.Replace(".pdf", ".zip"));

            reader.Close();
            reader.Dispose();
        }
        catch
        {
        }
        finally
        {
            GC.Collect();
        }
        return cnt - 1;

为清晰起见,我删除了上面的一些代码。

如果我将“使用”块删除PdfStamper,代码就可以了。我也试图调整PdfStamper的位置,看看我是否在错误的地方使用它。

我没有正确使用using块吗?或者我必须在这里修改一些代码序列?

1 个答案:

答案 0 :(得分:1)

你删除了一些必不可少的行;例如:我假设您要向PdfImportedPage的{​​{1}}添加PdfContentByte。如果是这样的话,你忽略了官方文档中给出的所有警告。

您应该用以下内容替换您的代码:

PdfWriter

如您所见,无需引入PdfReader reader = new PdfReader(pathToFile); int n = reader.NumberOfPages; int cnt; for (cnt = 1; cnt <= reader.NumberOfPages; cnt++) { reader = new PdfReader(pathToFile); reader.SelectPages(cnt.ToString()); MemoryStream memoryStream = new MemoryStream(); using (PdfStamper stamper = new PdfStamper(reader, memoryStream)) { stamper.SetEncryption( null, Encoding.ASCII.GetBytes("password_here"), PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128); } reader.Close(); // now do something with the memoryStream.ToArray() } Document对象。如果您使用这些类,则会丢弃原始页面中存在的所有交互性。如果原始页面的页面大小与A4不同,您也会遇到麻烦。

请注意,在使用PdfWriter时,您无法重复使用PdfReader实例。将PdfStamper实例传递给PdfReader后,该实例被篡改