我通過IIS Web應用程序合併XPS文件,但在合併過程中,它使文檔引用文件句柄保持打開狀態。在Windows WPF或控制檯應用程序中,我不擔心這些句柄,因爲它們會在應用程序關閉後發佈。回收應用程序池也會有效地關閉手柄。但是,由於緩存和性能的原因,我無法僅僅關閉應用程序池來關閉文件句柄。合併XPS文件留下打開的文件句柄以文檔引用
合併完成後有沒有辦法關閉這些文件句柄?我已經嘗試了幾種不同的合併方法,但下面的代碼給了我最好的結果:
private DocumentPaginator CreateMergedDocument(IEnumerable<string> xpsFiles) {
using (MemoryStream mergedStream = new MemoryStream()) {
using (var pkg = Package.Open(mergedStream, FileMode.Create, FileAccess.ReadWrite)) {
var pack = "pack://merged.xps";
var uri = new Uri(pack, UriKind.Absolute);
PackageStore.AddPackage(uri, pkg);
using (XpsDocument mergedDocument =
new XpsDocument(pkg, CompressionOption.Maximum, pack)) {
FixedDocumentSequence seqNew = new FixedDocumentSequence();
foreach (string sourceDocument in xpsFiles) {
using (XpsDocument xpsOld =
new XpsDocument(sourceDocument, FileAccess.Read)) {
FixedDocumentSequence seqOld = xpsOld.GetFixedDocumentSequence();
foreach (DocumentReference dr in seqOld.References) {
DocumentReference newDocumentReference = new DocumentReference();
newDocumentReference.Source = dr.Source;
(newDocumentReference as IUriContext).BaseUri =
(dr as IUriContext).BaseUri;
seqNew.References.Add(newDocumentReference);
}
}
}
XpsDocumentWriter xpsWriter = XpsDocument.CreateXpsDocumentWriter(mergedDocument);
xpsWriter.Write(seqNew);
PackageStore.RemovePackage(uri);
return seqNew.DocumentPaginator;
}
}
}
}
我就找到了文件句柄開放給xpsWriter.Write(seqNew)
行代碼。這是預期的,因爲它需要加載文件以複製到新的FixedDocumentSequence
。但是,如果XpsDocumentWriter
是一次性的並清理其非託管資源/文件句柄,那將會很好。
在我的研究中,我嘗試了其他一些方法。我嘗試過的一種方法是將每個頁面直觀地寫入SerializerWriterCollator
。我研究過的另一種方法是處理FixedPage內容並更新URI以複製圖像和字體流,並將原始XAML寫回XmlWriter
。沒有太好的工作。使用頁面可視化和SerializerWriterCollator
,我在合併的XPS上獲得了不正確的頁面大小,並且它正在切斷內容。使用原始的XmlWriter
方法,它混淆了合併XPS中的一些圖像,並錯誤地顯示了一些頁面內容。