From a1abf99afcca97f631e52268e877904a5c809cbc Mon Sep 17 00:00:00 2001 From: romain v Date: Wed, 6 Jan 2021 12:00:05 +0100 Subject: [PATCH] PdfMerger favors streams instead of byte[] Also, adds api similar to PdfDocument regarding streams --- src/UglyToad.PdfPig/Writer/PdfMerger.cs | 62 ++++++++++++++++++------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/src/UglyToad.PdfPig/Writer/PdfMerger.cs b/src/UglyToad.PdfPig/Writer/PdfMerger.cs index d884fcd9..cfc1e89c 100644 --- a/src/UglyToad.PdfPig/Writer/PdfMerger.cs +++ b/src/UglyToad.PdfPig/Writer/PdfMerger.cs @@ -43,11 +43,9 @@ throw new ArgumentNullException(nameof(file2)); } - return Merge(new[] - { - File.ReadAllBytes(file1), - File.ReadAllBytes(file2) - }, new [] { file1Selection, file2Selection }); + using var stream1 = new StreamInputBytes(File.OpenRead(file1)); + using var stream2 = new StreamInputBytes(File.OpenRead(file2)); + return Merge(new[] { stream1, stream2 }, new [] { file1Selection, file2Selection }); } /// @@ -55,21 +53,30 @@ /// public static byte[] Merge(params string[] filePaths) { - var bytes = new List(filePaths.Length); + var bytes = new List(filePaths.Length); - for (var i = 0; i < filePaths.Length; i++) + try { - var filePath = filePaths[i]; - - if (filePath == null) + for (var i = 0; i < filePaths.Length; i++) { - throw new ArgumentNullException(nameof(filePaths), $"Null filepath at index {i}."); + var filePath = filePaths[i]; + if (filePath == null) + { + throw new ArgumentNullException(nameof(filePaths), $"Null filepath at index {i}."); + } + + bytes.Add(new StreamInputBytes(File.OpenRead(filePath), true)); } - bytes.Add(File.ReadAllBytes(filePath)); + return Merge(bytes, null); + } + finally + { + foreach (var stream in bytes) + { + stream.Dispose(); + } } - - return Merge(bytes, null); } /// @@ -82,21 +89,42 @@ throw new ArgumentNullException(nameof(files)); } + return Merge(files.Select(f => new ByteArrayInputBytes(f)).ToArray(), pagesBundle); + } + + /// + /// Merge the set of PDF documents. + /// The caller must manage disposing the stream. The created PdfDocument will not dispose the stream. + /// + /// A list of streams for the files contents, this must support reading and seeking. + /// + /// + /// + public static byte[] Merge(IReadOnlyList streams, IReadOnlyList> pagesBundle = null) + { + if (streams == null) + { + throw new ArgumentNullException(nameof(streams)); + } + + return Merge(streams.Select(f => new StreamInputBytes(f, false)).ToArray(), pagesBundle); + } + + private static byte[] Merge(IReadOnlyList files, IReadOnlyList> pagesBundle = null) + { const bool isLenientParsing = false; var documentBuilder = new DocumentMerger(); foreach (var fileIndex in Enumerable.Range(0, files.Count)) { - var file = files[fileIndex]; - IReadOnlyList pages = null; if (pagesBundle != null && fileIndex < pagesBundle.Count) { pages = pagesBundle[fileIndex]; } - var inputBytes = new ByteArrayInputBytes(file); + var inputBytes = files[fileIndex]; var coreScanner = new CoreTokenScanner(inputBytes); var version = FileHeaderParser.Parse(coreScanner, isLenientParsing, Log);