簡體   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