2015-07-02 203 views
6

我試圖從C到C#的過渡,我有幾個關於將對象保存到文件和序列化的問題。保存對象/序列化

在C語言中,如果你想保存一個數據結構,我已經被教導過把它保存爲文本格式,因爲字符串通常是不必要的,而且作爲內存快照存在的二進制文件通常更好,因爲它不會「 t需要編碼/解碼並將字符串匹配到字段。 在C#中,該方法看起來不同,它將對象字段分別轉換爲字符串或其他格式,然後在必要時重建對象。我不確定二進制序列化如何工作,但我認爲它將數據轉換爲某種格式,並不存在作爲純粹的非格式化內存快照。

爲什麼沒有在C#中使用任何編碼/解碼的「內存快照」方法?我能想到的唯一原因是與其他代碼和環境的兼容性,也許它與對象與常規結構的複雜性有關。

+0

如果對象具有複雜的屬性,而不僅僅是值類型;那麼對象的每個「部分」將被存儲在不同的存儲位置;這些對象也可能包含其他對象。只是一個簡單的猜測,但執行這樣的邏輯來保存對象會非常複雜。 – daryal

+0

生產力的成本降低和好處之一是.NET對內存和硬件的抽象。如果你需要堅持基本的需求,讓框架處理繁重的工作(像往常一樣),用[Serializable]標記你的類並使用System.Runtime.Serialization.Formatters.Binary中可用的類。 – Michael

回答

2

在C#中,您無法訪問對象的內存佈局。您無法獲取對象的內存快照,或者從快照創建對象。事實上,你甚至沒有點(是的,你有他們在不安全的代碼,但你很少寫不安全的代碼)。

即使您確實有權訪問該對象使用的內存,它也可能無法保存到磁盤,然後重新加載。如果升級.NET環境,您可能會得到一個更好的優化器,它決定以不同的方式對對象的字段進行重新排序,或者使用不同的內存對齊方式。

因此總之 - 沒有訪問對象的內存,所以你需要按字段序列化。

好處是,既然.NET有反思,用這種方式序列化對象並不難。實際上,它比序列化一個保存指向其他C++類的C++類容易得多。

+0

因此。NET框架做了很多關於內存管理的事情,你沒有直接訪問內存,即使你這樣做也是危險的。這很有意義,謝謝! :) – user3604097

1

.NET二進制序列化格式遵循他們想要存儲的類型,並放入一些元數據,以便您知道如何解碼它(哪種類型,字段名稱等)。

這不是主要用於.NET語言的互操作 - 儘管它可能是。它用於與相同對象的過去和未來版本進行互操作,這些對象可以以對這些更改具有彈性的方式書寫 - 或者至少知道拒絕它們。在C中,如果以任何方式更改結構 - 並且您剛剛使用write()來存儲內存,那麼您可能還會選擇編寫一些元數據,以便您可以知道您是否擁有正確的版本(並需要轉換)。

另一個好處是.NET語言知道如何處理引用。默認情況下,C將write()地址,稍後將無用。 .NET也支持不應該被序列化的字段的想法(比如密碼) - 另一件你需要在C版本中手寫的東西。