繁体   English   中英

使用 PDFSharp 将多个 PDF 合并到一个非常大的 PDF 而不会用完 memory

[英]Merging multiple PDFs to a single very large PDF with PDFSharp without running out of memory

我正在使用 PDFsharp 将大量文件(存储在磁盘上)合并到一个 PDF 中。 有时 PDF 可能高达 700MB。 我正在使用提供的示例代码,它基本上创建了一个 output PdfDocument ,向其中添加页面,然后调用 outputDocument.Save(destinationPath),因此使用的 memory 的数量与生成的文档的大小大致相同。

有没有办法代替 stream 对文件的更改以避免 memory 消耗? 如果没有,是否有办法利用 MigraDoc 来做到这一点?

更新
根据评论中的建议,我整理了一些代码来关闭和重新打开文档,虽然 memory 的使用受到控制并且文件确实增长了,但它似乎没有附加页面。 如果我将“路径”设置为包含 3000 个单页文件的列表,我仍然会得到一个 500 页的文档。 这是代码:

var destinationFile = "c:\\test.pdf";
var directory = Path.GetDirectoryName(destinationFile);

if (!Directory.Exists(directory))
{
    Directory.CreateDirectory(directory);
}

var fs = new FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.ReadWrite);
var outputDocument = new PdfDocument(fs);
var count = 0;

// Iterate files (paths is a List<string> collection)
foreach (string path in paths)
{
    var inputDocument = PdfReader.Open(path, PdfDocumentOpenMode.Import);

    // Iterate pages
    for (int idx = 0; idx < inputDocument.PageCount; idx++)
    {
        // Get the page from the external document...
        PdfPage page = inputDocument.Pages[idx];
        // ...and add it to the output document.
        outputDocument.AddPage(page);
    }

    inputDocument.Dispose();
    
    count++;
    if (count % 500 == 0 || count == paths.Count)
    {
        outputDocument.Close();
        fs.Close();
        fs.Dispose();

        if (count < paths.Count)
        {
            fs = new FileStream(destinationFile, FileMode.Append, FileAccess.Write);
            outputDocument = new PdfDocument(fs);
        }
    }
}

更新 2
这是一些使用 PDFReader 关闭和重新打开文档的新代码。 程序正在合并 2000 4 页 140KB PDF,output 文件为 273MB。 我试过没有关闭和重新打开,关闭和重新打开每 1000、500、250 和 100 个文件。 结果如下:

No interval: 21 seconds, max memory 330MB 1000 interval: 30 seconds, max memory 490MB 500 interval: 55secs, max memory 710MB 250 interval: 1min 35sec, max memory 780MB 100 interval: 2min 55secs, max memory 850mb

class Program
{
    public static void Main(string[] args)
    {
        var files = new List<string>();
        var basePath = AppDomain.CurrentDomain.BaseDirectory;

        for (var i = 0; i < 2000; i++)
        {
            files.Add($"{basePath}\\sample.pdf");
        }
        DoMerge(files, $"{basePath}\\output.pdf");
    }

    private static void DoMerge(List<string> paths, string destinationFile)
    {

        var directory = Path.GetDirectoryName(destinationFile);

        if (!Directory.Exists(directory))
        {
            Directory.CreateDirectory(directory);
        }

        var outputDocument = new PdfDocument();
        var count = 0;

        // Iterate files
        foreach (string path in paths)
        {
            // Open the document to import pages from it.
            try
            {
                var inputDocument = PdfReader.Open(path, PdfDocumentOpenMode.Import);

                // Iterate pages
                for (int idx = 0; idx < inputDocument.PageCount; idx++)
                {
                    // Get the page from the external document...
                    PdfPage page = inputDocument.Pages[idx];
                    // ...and add it to the output document.
                    outputDocument.AddPage(page);
                }

                inputDocument.Dispose();
                
                count++;
                if (count % 500 == 0 || count == paths.Count)
                {
                    outputDocument.Save(destinationFile);
                    outputDocument.Close();
                    outputDocument.Dispose();

                    if (count < paths.Count)
                    {
                        outputDocument = PdfReader.Open(destinationFile, PdfDocumentOpenMode.Import);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
        }
    }
}

为了减少 memory 的占用空间,您可以不时关闭目标文件,然后再次打开它,然后将 append 更多 PDF 文件添加到它。
PDFsharp 不支持将数据交换到文件。

确保您的应用程序在 64 位模式下运行,以允许其使用超过 2 GiB 的 RAM。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM