将 MemoryStream 用于 iTextSharp 的 PdfWriter 输出时未填充流
Stream is not filled when using a MemoryStream for PdfWriter output from iTextSharp
我有以下问题。
这段代码工作正常
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
流包含大约 200Kb,保存的 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
之前我需要做一些操作,但我不知道是什么。
首先,如果你想return一个MemoryStream
方法中的对象,不要把它放到using
那个方法中的子句:当离开那个 using
块时,流对象被释放,所以你的方法的调用者得到一个他不会高兴的关闭流。
其次,如果您不想在关联的 Document
关闭时关闭 PdfWriter
写入的流,只需设置 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
.
我有以下问题。
这段代码工作正常
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
流包含大约 200Kb,保存的 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
之前我需要做一些操作,但我不知道是什么。
首先,如果你想return一个MemoryStream
方法中的对象,不要把它放到using
那个方法中的子句:当离开那个 using
块时,流对象被释放,所以你的方法的调用者得到一个他不会高兴的关闭流。
其次,如果您不想在关联的 Document
关闭时关闭 PdfWriter
写入的流,只需设置 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
.