Поток не заполняется при использовании вывода MemoryStream для PdfWriter из iTextSharp - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть следующая проблема.

Этот код отлично работает

private void ModifyAndSavePDF(Stream sourceFile, string text)
{
    using (var pdfWriterStream = new FileStream(@"d:/temp/test.pdf", FileMode.Create))
    {
        var reader = new PdfReader(sourceFile);
        var document = new Document(reader.GetPageSizeWithRotation(1));
        var writer = PdfWriter.GetInstance(document, pdfWriterStream);
        document.Open();
        for (var i = 1; i <= reader.NumberOfPages; i++)
        {
            document.NewPage();
            var importedPage = writer.GetImportedPage(reader, i);
            var contentByte = writer.DirectContent;
            //some more PDF editing stuff here. Not relevant.
        }
        document.Close();
        writer.Close();
        reader.Close();
    }
}

Это отлично работает.Поток sourceFile содержит около 200 КБ, и сохраненный файл PDF выглядит именно так, как я ожидаю.Хочу отметить, что до document.Close() длина потока pdfWriterStream составляла всего около 800 байт.

Моя проблема в том, что я не хочу сохранять это в файл на диске,вместо этого хотел бы иметь вывод в виде MemoryStream.Это, однако, я не могу получить работу, как я ожидаю.Моя первая попытка была такой:

private Stream ModifyAndSavePDF(Stream sourceFile, string text)
{
    using (var pdfWriterStream = new MemoryStream())
    {
        var reader = new PdfReader(sourceFile);
        var document = new Document(reader.GetPageSizeWithRotation(1));
        var writer = PdfWriter.GetInstance(document, pdfWriterStream);
        document.Open();
        for (var i = 1; i <= reader.NumberOfPages; i++)
        {
            document.NewPage();
            var importedPage = writer.GetImportedPage(reader, i);
            var contentByte = writer.DirectContent;
            //some more PDF editing stuff here. Not relevant.
        }
        document.Close();
        writer.Close();
        reader.Close();
    }
    return pdfWriterStream;
}

Конечно, это не сработает, поскольку, когда я вызываю document.Close(), pdfWriterStream также удаляется, и я не могу прочитать содержимое потока.

Вторая попытка:

private Stream ModifyAndSavePDF(Stream sourceFile, string text)
{
    var result = new MemoryStream();
    using (var pdfWriterStream = new MemoryStream())
    {
        var reader = new PdfReader(sourceFile);
        var document = new Document(reader.GetPageSizeWithRotation(1));
        var writer = PdfWriter.GetInstance(document, pdfWriterStream);
        document.Open();
        for (var i = 1; i <= reader.NumberOfPages; i++)
        {
            document.NewPage();
            var importedPage = writer.GetImportedPage(reader, i);
            var contentByte = writer.DirectContent;
            //some more PDF editing stuff here. Not relevant.
        }
        pdfWriterStream.Position = 0;
        pdfWriterStream.CopyTo(result);
        document.Close();
        writer.Close();
        reader.Close();
    }
    return result;
}

Я получаю проблему, как первый код в списке.pdfWriterStream на данный момент состоит только из около 800 байтов, и при копировании в result получаются только эти 800 байтов, а не весь файл.

Так что, похоже, document.Close() сбрасывает файл вбуфер, а затем удаляет его.Поэтому я думаю, что мне нужно сделать какую-то операцию, прежде чем я скопирую pdfWriterStream в result, но я не могу понять, что.

1 Ответ

0 голосов
/ 28 ноября 2018

Прежде всего, если вы хотите вернуть объект MemoryStream из метода , не помещайте его в предложение using в том же методе: при выходе из этого блока usingобъект потока удаляется, поэтому вызывающий ваш метод получает закрытый поток, который ему не понравится.

Во-вторых, если вы не хотите, чтобы поток, который записывает PdfWriter, былзакрыто, когда связанный Document закрыт, просто установите атрибут PdfWriter CloseStream на false.

Таким образом:

private Stream ModifyAndSavePDF(Stream sourceFile, string text)
{
    var pdfWriterStream = new MemoryStream();
    var reader = new PdfReader(sourceFile);
    var document = new Document(reader.GetPageSizeWithRotation(1));
    var writer = PdfWriter.GetInstance(document, pdfWriterStream);
    writer.CloseStream = false;
    document.Open();
    for (var i = 1; i <= reader.NumberOfPages; i++)
    {
        document.NewPage();
        var importedPage = writer.GetImportedPage(reader, i);
        var contentByte = writer.DirectContent;
        //some more PDF editing stuff here. Not relevant.
    }
    document.Close();
    reader.Close();

    return pdfWriterStream;
}

В стороне, вам не нужночтобы закрыть PdfWriter, он неявно закрывается, когда закрывается связанный Document.

И, кроме того, на первый взгляд, ваш метод выглядит так, как будто вы копируете какой-то оригинальный PDF-файл и вносите в него некоторые изменения.Обычно (в зависимости от точных изменений, которые вы хотите применить, то есть) это следует делать, используя PdfStamper, а не просто PdfWriter.

...