文档序列化和存储

更新:2007 年 11 月

Microsoft .NET Framework为创建和显示高质量的文档提供了一个强大环境。 增强功能可支持固定文档和流文档以及高级查看控件,这些增强功能与强大的二维和三维图形功能结合在一起,提高了 .NET Framework 应用程序的质量水平,增强了用户体验。 .NET Framework 的主要功能是能够灵活管理文档的内存中表现形式,而几乎每个应用程序都需要能够高效保存和加载数据存储区中的文档。 将文档从内部的内存中表现形式转换为外部数据存储区的过程称为序列化。 反之,读取数据存储区并重新创建原始内存中实例的过程则称为反序列化。

本主题包括下列各节。

  • 关于文档序列化
  • 插件序列化程序
  • 相关主题

关于文档序列化

理论上,对于应用程序来说,从内存中序列化文档和将文档反序列到原来的内存中都是透明的。 应用程序调用序列化程序“write”方法来保存文档,而反序列化程序“read”方法则访问数据存储区并在内存中重新创建原始实例。 对于应用程序来说,只要序列化和反序列化进程将文档重新创建为其原始格式,数据存储的特定格式通常无关紧要。

应用程序通常可提供多个序列化选项,用户可以使用这些选项将文档保存到不同的媒体或保存为不同格式。 例如,应用程序可提供“另存为”选项将文档存储到磁盘文件、数据库或 Web 服务。 同样,不同的序列化程序可将文档存储为不同格式,例如 HTML、RTF、XML、XPS 或第三方格式。 对于应用程序,序列化定义了一个接口,该接口可以隔离每个特定序列化程序的实现内部的存储媒体的详细信息。 除封装存储详细信息这个优点之外,.NET FrameworkSystem.Windows.Documents.SerializationAPI 还提供了多个其他重要功能。

.NET Framework 3.0 文档序列化程序的功能

  • 通过直接访问高级别文档对象(逻辑树和可视化对象),可以有效存储已分页的内容、二维/三维元素、图像、媒体、超链接、批注以及其他支持内容。

  • 同步和异步操作。

  • 支持具有以下增强功能的插件序列化程序:

    • 供所有 .NET Framework 应用程序使用的系统级访问。

    • 简单应用程序插件的发现功能。

    • 第三方自定义插件的简单部署、安装和更新。

    • 对自定义运行时设置和选项的用户界面支持。

XPS 打印路径

Microsoft .NET Framework XPS 打印路径还通过打印输出为编写文档提供了一种可扩展机制。XPS 可以作为文档文件格式,也可以作为 Windows Vista 的本机打印后台格式。XPS 文档可直接发送到与 XPS 兼容的打印机,而无需转换为中间格式。 有关打印路径输出选项和功能的其他信息,请参见打印概述

插件序列化程序

System.Windows.Documents.Serialization API 可对以下各项提供支持:与应用程序分开安装、在运行时绑定并使用 SerializerProvider 发现机制访问的插件序列化程序和链接序列化程序。 插件序列化程序提供了增强功能,可以简化部署和系统范围的使用。 还可针对无法在其中访问插件序列化程序的部分可信环境(例如 XAML 浏览器应用程序 (XBAP))实现链接序列化程序。 链接序列化程序基于 SerializerWriter 类的派生的实现,将被编译并直接链接到应用程序。 插件序列化程序和链接序列化程序都是通过相同的公共方法和事件来运行的,这样可以方便地在同一应用程序中使用其中一种或两种序列化程序。

插件序列化程序对应用程序开发人员很有帮助:它向新的存储设计和文件格式提供扩展性,而无需在生成时对每种潜在的格式进行直接编码。 插件序列化程序还通过为自定义或专有文件格式提供部署、安装和更新系统可访问插件的标准方法,使第三方开发人员受益匪浅。

使用插件序列化程序

插件序列化程序易于使用。 SerializerProvider 类为系统上安装的每个插件枚举一个 SerializerDescriptor 对象。 IsLoadable 属性根据当前配置筛选已安装的插件,并验证应用程序是否可以加载和使用序列化程序。 SerializerDescriptor 还提供了其他属性(如 DisplayNameDefaultFileExtension),应用程序可以使用这些属性来提示用户选择可用输出格式的序列化程序。 XPS 的默认插件序列化程序随 .NET Framework 一起提供,并会始终进行枚举。 用户选择输出格式之后,将使用 CreateSerializerWriter 方法创建特定格式的 SerializerWriter。 然后可以调用 SerializerWriter.Write 方法将文档流输出到数据存储区。

下面的示例阐释使用“PlugInFileFilter”属性中的 SerializerProvider 方法的应用程序。 PlugInFileFilter 枚举已安装的插件,并使用 SaveFileDialog 的可用文件选项生成筛选器字符串。

// ------------------------ PlugInFileFilter --------------------------
/// <summary>
///   Gets a filter string for installed plug-in serializers.</summary>
/// <remark>
///   PlugInFileFilter is used to set the SaveFileDialog or
///   OpenFileDialog "Filter" property when saving or opening files
///   using plug-in serializers.</remark>
private string PlugInFileFilter
{
    get
    {   // Create a SerializerProvider for accessing plug-in serializers.
        SerializerProvider serializerProvider = new SerializerProvider();
        string filter = "";

        // For each loadable serializer, add its display
        // name and extension to the filter string.
        foreach (SerializerDescriptor serializerDescriptor in
            serializerProvider.InstalledSerializers)
        {
            if (serializerDescriptor.IsLoadable)
            {
                // After the first, separate entries with a "|".
                if (filter.Length > 0)   filter += "|";

                // Add an entry with the plug-in name and extension.
                filter += serializerDescriptor.DisplayName + " (*" +
                    serializerDescriptor.DefaultFileExtension + ")|*" +
                    serializerDescriptor.DefaultFileExtension;
            }
        }

        // Return the filter string of installed plug-in serializers.
        return filter;
    }
}

用户选择输出文件名之后,下面的示例阐释如何使用 CreateSerializerWriter 方法以指定格式存储给定文档。 有关完整的示例,请参见文档序列化示例

// Create a SerializerProvider for accessing plug-in serializers.
SerializerProvider serializerProvider = new SerializerProvider();

// Locate the serializer that matches the fileName extension.
SerializerDescriptor selectedPlugIn = null;
foreach ( SerializerDescriptor serializerDescriptor in
                serializerProvider.InstalledSerializers )
{
    if ( serializerDescriptor.IsLoadable &&
         fileName.EndsWith(serializerDescriptor.DefaultFileExtension) )
    {   // The plug-in serializer and fileName extensions match.
        selectedPlugIn = serializerDescriptor;
        break; // foreach
    }
}

// If a match for a plug-in serializer was found,
// use it to output and store the document.
if (selectedPlugIn != null)
{
    Stream package = File.Create(fileName);
    SerializerWriter serializerWriter =
        serializerProvider.CreateSerializerWriter(selectedPlugIn,
                                                  package);
    IDocumentPaginatorSource idoc =
        flowDocument as IDocumentPaginatorSource;
    serializerWriter.Write(idoc.DocumentPaginator, null);
    package.Close();
    return true;
}

安装插件序列化程序

SerializerProvider 类为插件序列化程序的发现和访问提供高级别应用程序接口。SerializerProvider 为应用程序定位和提供一个系统上已安装的可访问序列化程序的列表。 已安装序列化程序的具体信息通过注册表设置来定义。 使用 RegisterSerializer 方法可向注册表添加插件序列化程序;或者如果尚未安装 .NET Framework,插件安装脚本自身则可以直接设置注册表值。 使用 UnregisterSerializer 方法可以移除以前已安装的插件,或者类似地通过卸载脚本来重置注册表设置。

创建插件序列化程序

插件序列化程序和链接序列化程序使用同一公开的公共方法和事件,并且类似地可将其设计为以同步或异步方式运行。 创建插件序列化程序通常应执行下列三个基本步骤:

  1. 首先以链接序列化程序的形式实现和调试序列化程序。 开始时通过创建直接编译和链接到测试应用程序的序列化程序,可以提供对断点以及其他有助于测试的调试服务的完全访问权限。

  2. 完全测试序列化程序之后,会添加一个 ISerializerFactory 界面以创建插件。 ISerializerFactory 界面允许对所有 .NET Framework 对象的完全访问,包括逻辑树、UIElement 对象、IDocumentPaginatorSourceVisual 元素。 此外,ISerializerFactory 提供的同步和异步方法和事件与链接序列化程序使用的方法和事件相同。 由于输出大型文档需要一定时间,因此推荐使用异步操作以维持响应用户交互,如果数据存储区出现问题,则提供“取消”选项。

  3. 创建插件序列化程序之后,将实现安装脚本以分发和安装(以及卸载)插件(请参见上面的“安装插件序列化程序”)。

请参见

任务

打印 XPS 文档

文档序列化示例

概念

Windows Presentation Foundation 中的文档

打印概述

参考

System.Windows.Documents.Serialization

XpsDocumentWriter

XpsDocument

其他资源

XPS