PdfiumViewer组件扩展(Pdfium.Net.Free)--打开大文件处理
项目地址:
Pdfium.Net:https://github.com/1000374/Pdfium.Net.Free
PdfiumViewer:https://github.com/1000374/PdfiumViewer
Pdfium.Net.Free 支持
-
.NETFramework 4.0
-
.NETFramework 4.5
-
.NETStandard 2.0
- .Net8.0
可以和PdfiumViewer.Free共同使用预览、编辑pdf,也可以直接引用Pdfium.Net.Free 操作pdf,Pdfium.Net.Free封装了现有Pdfium的函数,实现了部分操作pdf的功能,部分功能等待后续~~
PDFium支持打开文件支持传入文件流
加载PDF到内存流(此种方式不占用文件):
var stream=new MemoryStream(File.ReadAllBytes(fileName)); var doc=PdfDocumentGdi.Load(this, stream);
但是当pdf文件超过85000字节后,内存既不像引用类型那样分配到普通堆上,也不像值类型那样分配到栈上,而是分配到了一个特殊的称为LOH的内部堆上,这部分的内存只有在GC执行完全回收,也就是回收二代内存的时候才会回收。
因此,考虑如下情形:
假设你的程序每次都要分配一个大型对象(大于85000字节),但却很少分配小对象,导致2代垃圾回收从不执行,即使这些大对象不再被引用,依然得不到释放,最终导致内存泄漏。
解决方案:
1.不考虑文件被占用可使用:
var filestm = new FileStream(fileName, FileMode.Open); var doc=PdfDocumentGdi.Load(this, stream);
2.但是 有些情况下不想占用文件:
nuget 引用 Microsoft.IO.RecyclableMemoryStream
RecyclableMemoryStreamManager manager;
int multiple = 5;
int blockSize = multiple * 1024;
int largeBufferMultiple = 1024 * 1024;
int maxBufferSize = 16 * largeBufferMultiple;
int maximumFreeSmallPoolBytes = 100 * blockSize / multiple;
int maximumFreeLargePoolBytes = maxBufferSize * 4;
var options = new RecyclableMemoryStreamManager.Options()
{
BlockSize = blockSize,
LargeBufferMultiple = largeBufferMultiple,
MaximumBufferSize = maxBufferSize,
GenerateCallStacks = true,
AggressiveBufferReturn = true,
MaximumLargePoolFreeBytes = maximumFreeLargePoolBytes,
MaximumSmallPoolFreeBytes = maximumFreeSmallPoolBytes,
};
manager = new RecyclableMemoryStreamManager(options);
var stream = manager.GetStream();
using (var filestm = new FileStream(fileName, FileMode.Open))
{
filestm.CopyTo(stream);
}
var doc=PdfDocumentGdi.Load(this, stream);
这两种方式都可以在打开第二份pdf时释放上一份的内存



浙公网安备 33010602011771号