我有以下问题。
此代码可以正常工作
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
之前需要做一些操作,但是我不知道要做什么。
答案 0 :(得分:1)
首先,如果要从方法中返回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
。