使用pdf压模时出现内存异常

时间:2015-10-14 10:34:14

标签: .net itextsharp

我正在使用pdf压模来加密带有密码的pdf。我们的要求是并行执行50个pdf文件,每个文件的大小最多可达300 MB。

如果我运行代码并并行加密50个文件2-3次,我就会出现内存异常。你能帮忙弄清楚我做错了吗?

我甚至尝试使用GC.Collect和GC.WaitForPendingFinalizers,但问题仍然存在。

我在下面创建了一个测试用例,我将相同的文件复制50次并并行执行。

感谢您的帮助。

我的代码如下:

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        int[] nums = Enumerable.Range(0, 50).ToArray();
        string pdfTestDir = @"C:\ztemp\pdfTest";
        string originalFile = @"C:\Ztemp\Original.pdf";
        string newFile = @"C:\Ztemp\pdfTest\NewPdf_";
        if (Directory.Exists(pdfTestDir)) { Directory.Delete(pdfTestDir, true); }
        Directory.CreateDirectory(pdfTestDir);
        if (Directory.Exists(pdfTestDir))
        {
            Parallel.ForEach<int>(nums, t =>
            {
                try
                {
                    int userCopy = t + 1;

                    string newFilePath = newFile + userCopy.ToString() + ".pdf";
                    System.IO.File.Copy(originalFile, newFilePath);

                    ProtectPdf(newFilePath);
                }
                catch (Exception ex)
                {
                    throw ex;
                }


            });
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        MessageBox.Show("Done");
    }
    catch (Exception exc)
    {
        MessageBox.Show(exc.Message);
    }
}


public void ProtectPdf(string file)
{
    try
    {
        FileInfo fileInfo = new FileInfo(file);
        string password = "password";
        // Default strength; 128
        var strength = PdfWriter.ENCRYPTION_AES_128;
        // Get permission; default is PdfWriter.ALLOW_SCREENREADER
        var permissions = PdfWriter.ALLOW_SCREENREADERS; 
        var tempInfo = new FileInfo(fileInfo.FullName.ToLower().Replace(".pdf", ".enrypted.pdf"));
        if (tempInfo.Exists)
        {
            tempInfo.Delete();
        }
        var sInFilePath = fileInfo.FullName;
        var sOutFilePath = tempInfo.FullName;

        using (var existingFileStream = new FileStream(sInFilePath, FileMode.Open))
        using (var newFileStream = new FileStream(sOutFilePath, FileMode.Create))
        {
            // Open existing PDF
            var pdfReader = new PdfReader(existingFileStream);

            // PdfStamper, which will create
            var stamper = new PdfStamper(pdfReader, newFileStream);
            try
            {
                stamper.SetEncryption(strength, password, password, permissions);
                stamper.SetFullCompression();

                stamper.Close();
                stamper.Dispose();
                pdfReader.Close();
                pdfReader.Dispose();
                newFileStream.Close();
                newFileStream.Dispose();
                existingFileStream.Close();
                existingFileStream.Dispose();

            }
            catch (Exception ex)
            {
                stamper.Close();
                stamper.Dispose();
                pdfReader.Close();
                pdfReader.Dispose();
                throw ex;
            }
        }
        fileInfo.Delete();
        tempInfo.MoveTo(sInFilePath);
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
    catch (Exception ex)
    {
        throw ex;
    }

}

0 个答案:

没有答案