处理分析、识别或合成结果时,你可能需要遍历文档页面及其上的块。在这种情况下,需要注意的是:当你请求查看或编辑某个文档元素 (例如页面或块) 时,相关数据会加载到内存中,并且会一直保留,直到被显式卸载。这可能导致“内存不足”错误。为避免这种情况,请遵循以下建议。
当您使用 FRDocument 对象的处理方法时,在 Linux 和 macOS 中,Layout 和图像文档会自动卸载到磁盘。在 Windows 中,Layout 和图像文档也可以自动保存到磁盘;不过,此行为取决于所选的 PageFlushingPolicy 属性值。
但是,如果您请求文档的某个页面及其块以进行查看或编辑,数据不会自动卸载或保存。如果您要查看或编辑多个页面,则应在完成每个页面的操作后卸载其数据。这意味着您应调用 FRPage 对象的 Flush 方法。
在 Windows 上使用 .NET 的用户还应调用 GC.Collect 和 GC.WaitForPendingFinalizers。
另一方面,如果您在遍历页面时做了某些更改,则需要调用 Flush 方法来保存这些更改。否则,例如,当您调用 SaveToFolder 或相应 FRDocument 的某个导出方法时,您的更改会保存到文件夹 (或导出的文档) 中,但会从您当前使用的对象中清除。
在 Windows 中,Flush 方法的行为取决于 IFRDocument::PageFlushingPolicy 属性的值。如果 PageFlushingPolicy 的值为 PFP_FlushToDisk,调用该方法会将 Layout 和图像文档卸载到磁盘。如果其值为 PFP_Auto,那么当文档页数超过 30 页时,调用该方法会将数据卸载到磁盘;否则,数据会保留在内存中。如果其值为 PFP_KeepInMemory,则数据不会被卸载。这在同一解决方案中同时处理小型和大型文档时非常方便,因为您可以使用相同的处理代码。
FREngine.IFRPages pages = document.Pages;
int pagesCount = pages.Count;
for (int i = 0; i < pagesCount; i++)
{
FREngine.IFRPage page = pages.Item(i);
// 遍历页面——处理块、段落和字符
iteratePage(page);
// 强制垃圾回收器释放页面中所有未引用的对象
GC.Collect();
GC.WaitForPendingFinalizers();
// 卸载未使用的页面数据
// 如果页面在 iteratePage() 中已修改,请调用 Flush(true) 以保留更改
page.Flush(true);
// 如果无需保留更改,请调用 Flush(false)
// page.Flush(false);
}
FREngine::IFRPagesPtr pages = document->Pages;
int pagesCount = pages->Count;
for( int i = 0; i < pagesCount; i++ ) {
FREngine::IFRPagePtr page = pages->Item( i );
// 遍历页面——处理块、段落和字符
iteratePage( page );
// 卸载未使用的页面数据
// 如果页面在 iteratePage() 中已修改,请调用 Flush( true ) 以保留更改
page->Flush( true );
// 如果无需保留更改,请调用 Flush(false)
// page->Flush( false );
}
另请参阅
FRDocument
使用 Text