iText 8.0.5中doc.Close()导致MemoryStream被释放的问题求助
解决iText 8.0.5中返回MemoryStream被释放的问题
核心原因是iText 8的PdfWriter默认会在关联的PdfDocument关闭时,自动关闭底层的流对象——这和iTextSharp的行为完全不同,哪怕你去掉using语句,只要关闭Document/PdfDocument,MemoryStream还是会被释放。
解决方案:禁用PdfWriter的自动关闭流功能
修改代码,在初始化PdfWriter时关闭自动流关闭行为,同时在返回MemoryStream前重置其读取位置:
public MemoryStream GenerateReportPdf(ReportData rptData) { MemoryStream ms = new MemoryStream(); // 配置PdfWriter不自动关闭底层流 PdfWriter writer = new PdfWriter(ms); writer.SetCloseStream(false); var pdfDoc = new PdfDocument(writer); var doc = new Document(pdfDoc); styles = GetStyles(); AddReportContent(doc, rptData); // 关闭文档对象 doc.Close(); pdfDoc.Close(); // 重置流位置到开头,确保调用方能正确读取内容 ms.Position = 0; return ms; }
为什么之前的尝试无效?
- 去掉
using没用:因为PdfWriter的默认行为就是关闭流,和using语句无关 - 转字节数组后PDF无效:大概率是你在复制字节数组时,没等文档完全关闭就读取流内容,导致拿到的是不完整的PDF数据。如果想用这种方法,正确步骤是:
public MemoryStream GenerateReportPdf(ReportData rptData) { using (MemoryStream ms = new MemoryStream()) { var pdfDoc = new PdfDocument(new PdfWriter(ms)); var doc = new Document(pdfDoc); styles = GetStyles(); AddReportContent(doc, rptData); // 必须先关闭文档,确保所有PDF内容写入流 doc.Close(); pdfDoc.Close(); // 复制完整的字节数组并创建新流 byte[] pdfBytes = ms.ToArray(); return new MemoryStream(pdfBytes); } }
注意事项
- 调用方拿到返回的
MemoryStream后,使用完毕需要自行负责释放 - 务必执行
ms.Position = 0,否则调用方读取流时会从末尾开始,无法获取有效内容
内容的提问来源于stack exchange,提问作者Scott Rassbach
相关产品推荐
相关产品推荐

