文档序列化和存储

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

关于文档序列化

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

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

.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 接口允许完全访问包括逻辑树、UIElement 对象、IDocumentPaginatorSourceVisual 元素的所有 .NET Framework 对象。 此外,ISerializerFactory 提供了链接序列化程序使用的相同同步和异步方法和事件。 由于输出大型文档需要一定时间,因此推荐使用异步操作以维持响应用户交互,并在数据存储出现问题时提供“取消”选项。

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

另请参阅