Сериализация и хранение документов

Microsoft .NET Framework предоставляет среду с широкими возможностями для создания и отображения документов высокого качества. Улучшенные возможности, поддерживающие фиксированные и потоковые документы, улучшенные элементы управления просмотром в сочетании с мощными возможностями двумерной и трехмерной графики позволяют вывести приложения .NET Framework на новый уровень качества и удобства для пользователей. Гибкое управление представлением документа в памяти является отличительной особенностью .NET Framework, а возможность эффективно сохранять и загружать документы из хранилища данных необходима практически во всех приложениях. Процесс преобразования документа из внутреннего представления в памяти во внешнее хранилище данных называется сериализацией. Обратный процесс чтения хранилища данных и воссоздания исходного экземпляра в памяти называется десериализацией.

О сериализации документов

В идеальном случае процесс сериализации и десериализации документа из памяти и в память прозрачен для приложения. Приложение вызывает метод write сериализатора для сохранения документа, в то время как метод read десериализатора осуществляет доступ к хранилищу данных и воссоздает исходный экземпляр в памяти. Как правило, формат хранения данных не имеет значения для приложения при условии, что в процессе сериализации и десериализации воссоздается документ в исходной форме.

Приложения часто предоставляют несколько параметров сериализации, которые позволяют пользователям сохранять документы на другом носителе или в другом формате. Например, приложение может предложить варианты "Сохранить как" для сохранения документа в файл на диске, базу данных или веб-службу. Аналогичным образом разные сериализаторы могут сохранять документ в различных форматах, например в HTML, RTF, XML, XPS или в ином стороннем формате. Для приложения сериализация определяет интерфейс, который изолирует сведения о носителе в реализации каждого определенного сериализатора. Помимо преимуществ инкапсуляции сведений о хранении, API-интерфейсы .NET Framework System.Windows.Documents.Serialization предоставляют несколько других важных функций.

Компоненты сериализаторов документов .NET Framework 3.0

  • Прямой доступ к высокоуровневым объектам документа (логическое дерево и визуальные элементы) позволяет эффективно хранить разделенное на страницы содержимое, двухмерные и трехмерные элементы, изображения, мультимедиа, гиперссылки, аннотации и другое содержимое поддержки.

  • Синхронные и асинхронные операции.

  • Поддержка сериализаторов подключаемых модулей с расширенными возможностями:

    • Доступ на уровне системы для использования всеми приложениями .NET Framework.

    • Удобное обнаружение подключаемых модулей приложения.

    • Простое развертывание, установка и обновление пользовательских подключаемых модулей сторонних производителей.

    • Поддержка интерфейса пользователя для пользовательских параметров и настроек среды выполнения.

Способ печати XPS

Путь печати Microsoft .NET Framework XPS также предоставляет расширяемый механизм записи документов посредством вывода на печать. XPS выступает как формат файла документа и имеет собственный формат очереди печати для ОС Windows Vista. Документы XPS можно отправлять непосредственно на совместимые со стандартом XPS принтеры, без преобразования в промежуточный формат. См. дополнительные сведения о параметрах и возможностях вывода пути печати в разделе Общие сведения о печати.

Подключаемые сериализаторы

API-интерфейсы System.Windows.Documents.Serialization обеспечивают поддержку для подключаемых и связанных сериализаторов, которые устанавливаются отдельно от приложения, связываются во время выполнения и доступ к которым осуществляется с помощью механизма обнаружения SerializerProvider. Подключаемые сериализаторы обеспечивают расширенные преимущества для простоты развертывания и использования в масштабах системы. Связанные сериализаторы также можно реализовать для сред с частичным доверием, таких как браузерные приложения XAML (XBAP), где подключаемые сериализаторы недоступны. Связанные сериализаторы, основанные на производной реализации класса SerializerWriter, компилируются и связываются непосредственно в приложение. Подключаемые и связанные сериализаторы функционируют через идентичные открытые методы и события, упрощающие использование любого из этих типов сериализаторов (или обоих типов) в приложении.

Подключаемые сериализаторы помогают разработчикам приложений, обеспечивая расширяемость новых проектируемых систем хранения и файловых форматов и избавляя от необходимости создавать код напрямую для каждого потенциального формата во время создания. Подключаемые сериализаторы помогают и сторонним разработчикам, предоставляя стандартизированные средства развертывания, установки и обновления доступных системе подключаемых модулей для пользовательских или собственных форматов файлов.

Использование подключаемого сериализатора

Использовать подключаемые сериализаторы достаточно просто. В классе SerializerProvider перечисляются объекты SerializerDescriptor для каждого подключаемого модуля, установленного в системе. Свойство IsLoadable фильтрует установленные подключаемые модули с учетом текущей конфигурации и проверяет, что сериализатор можно загрузить и использовать в приложении. Объект SerializerDescriptor также предоставляет другие свойства, такие как DisplayName и DefaultFileExtension, с помощью которых приложение может предоставлять пользователю возможность выбора сериализатора в соответствии с доступным форматом вывода. Подключаемый сериализатор по умолчанию для XPS предоставляется с помощью .NET Framework и всегда перечисляется. После выбора пользователем формата вывода с помощью метода CreateSerializerWriter создается объект SerializerWriter в соответствии с определенным форматом. Затем можно вызвать метод SerializerWriter.Write, чтобы вывести поток документа в хранилище данных.

В следующем примере показано приложение, которое использует метод SerializerProvider в свойстве «PlugInFileFilter». Свойство 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 объекты IDocumentPaginatorSource и элементы Visual. Кроме того, ISerializerFactory предоставляет те же синхронные и асинхронные методы и события, которые используются связанными сериализаторами. Поскольку на вывод крупных документов может потребоваться время, рекомендуется использовать асинхронные операции, чтобы сохранить возможность взаимодействия с пользователем и предоставить возможность отмены, если с источником данных произойдет проблема.

  3. После создания подключаемого сериализатора сценарий установки реализуется для распространения и установки (и удаления) подключаемого модуля (см. Установка подключаемых сериализаторов выше).

См. также