我正在使用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;
}
}