文件序列化與儲存

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 文件序列化程式的功能

  • 直接存取高階文件物件 (邏輯樹狀結構和視覺物件) 可以有效率地儲存分頁內容、2D/3D 項目、影像、媒體、超連結、註解和其他支援內容。

  • 同步和非同步作業。

  • 透過增強的功能支援外掛程式序列化程式:

    • 供所有 .NET Framework 應用程式使用的系統範圍存取權。

    • 輕鬆探索應用程式外掛程式。

    • 輕鬆部署、安裝和更新自訂的協力廠商外掛程式。

    • 可支援自訂執行階段設定和選項的使用者介面。

XPS 列印路徑

.NET Framework XPS 列印路徑也提供可擴充機制,透過列印輸出的方式寫入文件。 XPS 可同時作為文件檔案格式,以及 Windows Vista 的原生列印多工緩衝處理格式。 XPS 文件可以直接傳送至 XPS 相容的印表機,而不需要轉換成中繼格式。 如需列印路徑輸出選項和功能的其他資訊,請參閱列印概觀

外掛程式序列化程式

System.Windows.Documents.Serialization API 可同時支援外掛程式序列化程式和連結的序列化程式,這些序列化程式會與應用程式分開安裝、在執行階段繫結,並透過 SerializerProvider 探索機制來存取。 外掛程式序列化程式提供增強的優點,以便進行部署並在整個系統內使用。 在無法存取外掛程式序列化程式的部分信任環境中 (例如 XAML 瀏覽器應用程式),也可以實作連結的序列化程式。 連結的序列化程式 (根據 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. 建立外掛程式序列化程式之後,實作用於散發和安裝 (及解除安裝) 外掛程式的安裝指令碼 (請參閱上面的<安裝外掛程式序列化程式>)。

另請參閱