MemoryStream - 合并 PDF 时无法访问已关闭的流
MemoryStream - Cannot access a closed Stream when merging PDFs
你能告诉我,我的代码有什么问题吗?我用它来合并 PDF,我创建了一个内存流,然后将其输出为 PDF。它对我来说工作正常,但有些用户无法在 IE 中下载文件,或在 Chrome:
中出现网络错误
public static MemoryStream MergePdfForms(List<byte[]> files)
{
if (files.Count > 1)
{
PdfReader pdfFile;
Document doc;
PdfWriter pCopy;
MemoryStream msOutput = new MemoryStream();
pdfFile = new PdfReader(files[0]);
doc = new Document();
pCopy = new PdfSmartCopy(doc, msOutput);
doc.Open();
for (int k = 0; k < files.Count; k++)
{
pdfFile = new PdfReader(files[k]);
for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
{
((PdfSmartCopy)pCopy).AddPage(pCopy.GetImportedPage(pdfFile, i));
}
pCopy.FreeReader(pdfFile);
}
pdfFile.Close();
pCopy.Close();
doc.Close();
return msOutput;
}
else if (files.Count == 1)
{
return new MemoryStream(files[0]);
}
return null;
}
经过调试,我发现内存流msOutput有一些错误:
是什么原因造成的,如何避免?
谢谢。
设置CloseStream
为false
,否则调用pCopy.Close()
.
时输出流将被关闭
pCopy = new PdfSmartCopy(doc, msOutput) { CloseStream = false };
说明
网上找不到文档,只好直接看源码
这是 PdfSmartCopy
class 的声明:
public class PdfSmartCopy : PdfCopy
{
// ...
public PdfSmartCopy(Document document, Stream os) : base(document, os) {
// ...
}
// ...
}
这是 PdfCopy
class 的声明:
public class PdfCopy : PdfWriter
{
// ...
public PdfCopy(Document document, Stream os) : base(new PdfDocument(), os) {
// ...
}
// ...
}
PdfWriter
class的声明:
public class PdfWriter : DocWriter,
IPdfViewerPreferences,
IPdfEncryptionSettings,
IPdfVersion,
IPdfDocumentActions,
IPdfPageActions,
IPdfIsoConformance,
IPdfRunDirection,
IPdfAnnotations
{
// ...
protected PdfWriter(PdfDocument document, Stream os) : base(document, os) {
// ...
}
// ...
}
最后,DocWriter
class的声明:
public abstract class DocWriter : IDocListener
{
// ...
// default value is true
protected bool closeStream = true;
public virtual bool CloseStream {
get {
return closeStream;
}
set {
closeStream = value;
}
}
protected DocWriter(Document document, Stream os)
{
this.document = document;
this.os = new OutputStreamCounter(os);
}
public virtual void Close() {
open = false;
os.Flush();
if (closeStream) // <-- Take a look at this line
os.Close();
}
// ...
}
你能告诉我,我的代码有什么问题吗?我用它来合并 PDF,我创建了一个内存流,然后将其输出为 PDF。它对我来说工作正常,但有些用户无法在 IE 中下载文件,或在 Chrome:
中出现网络错误public static MemoryStream MergePdfForms(List<byte[]> files)
{
if (files.Count > 1)
{
PdfReader pdfFile;
Document doc;
PdfWriter pCopy;
MemoryStream msOutput = new MemoryStream();
pdfFile = new PdfReader(files[0]);
doc = new Document();
pCopy = new PdfSmartCopy(doc, msOutput);
doc.Open();
for (int k = 0; k < files.Count; k++)
{
pdfFile = new PdfReader(files[k]);
for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
{
((PdfSmartCopy)pCopy).AddPage(pCopy.GetImportedPage(pdfFile, i));
}
pCopy.FreeReader(pdfFile);
}
pdfFile.Close();
pCopy.Close();
doc.Close();
return msOutput;
}
else if (files.Count == 1)
{
return new MemoryStream(files[0]);
}
return null;
}
经过调试,我发现内存流msOutput有一些错误:
是什么原因造成的,如何避免?
谢谢。
设置CloseStream
为false
,否则调用pCopy.Close()
.
pCopy = new PdfSmartCopy(doc, msOutput) { CloseStream = false };
说明
网上找不到文档,只好直接看源码
这是 PdfSmartCopy
class 的声明:
public class PdfSmartCopy : PdfCopy
{
// ...
public PdfSmartCopy(Document document, Stream os) : base(document, os) {
// ...
}
// ...
}
这是 PdfCopy
class 的声明:
public class PdfCopy : PdfWriter
{
// ...
public PdfCopy(Document document, Stream os) : base(new PdfDocument(), os) {
// ...
}
// ...
}
PdfWriter
class的声明:
public class PdfWriter : DocWriter,
IPdfViewerPreferences,
IPdfEncryptionSettings,
IPdfVersion,
IPdfDocumentActions,
IPdfPageActions,
IPdfIsoConformance,
IPdfRunDirection,
IPdfAnnotations
{
// ...
protected PdfWriter(PdfDocument document, Stream os) : base(document, os) {
// ...
}
// ...
}
最后,DocWriter
class的声明:
public abstract class DocWriter : IDocListener
{
// ...
// default value is true
protected bool closeStream = true;
public virtual bool CloseStream {
get {
return closeStream;
}
set {
closeStream = value;
}
}
protected DocWriter(Document document, Stream os)
{
this.document = document;
this.os = new OutputStreamCounter(os);
}
public virtual void Close() {
open = false;
os.Flush();
if (closeStream) // <-- Take a look at this line
os.Close();
}
// ...
}