2012-11-12 65 views
6

是否有可能反序列化二進制文件的一部分?反序列化二進制文件的一部分

基本上我有一個類似於下面的對象,我將其序列化爲一個二進制文件。

public class MyObject 
{ 
    public string Name { get; set; } 

    public int Value { get; set; } 

    pubic IList<MyOtherObject> { get; set; } //lots of data in her (order of kB-MB) 
} 

我想什麼它能夠通過填充一個ListView的文件選擇目的的方式反序列化僅NameValue,然後在需要的時候反序列化文件的剩餘部分(即用戶選擇從該文件ListView

與往常一樣,任何幫助非常感謝,如果任何第三方庫的建議,他們將需要能夠在商業環境中放心使用。

+1

可能是值得提到你如何序列化文件在第一個地方 – musefan

+0

這裏有一個類似的問題:http://stackoverflow.com/questions/1572999/c-sharp-partial-deserialization可能包含您正在尋找的答案。 –

+0

只需要確認,列表視圖項目代表二進制文件的各個部分,您只需要加載用戶選擇的那些部分? – Derek

回答

6

protobuf-net可以做到這一點,因爲它不綁定到特定類型;例如:

using ProtoBuf; 
using System.Collections.Generic; 
using System.IO; 

[ProtoContract] 
public class MyOtherObject { } 
[ProtoContract] 
public class MyObject 
{ 
    [ProtoMember(1)] 
    public string Name { get; set; } 
    [ProtoMember(2)] 
    public int Value { get; set; } 
    [ProtoMember(3)] 
    public IList<MyOtherObject> Items { get; set; } 
} 

[ProtoContract] 
public class MyObjectLite 
{ 
    [ProtoMember(1)] 
    public string Name { get; set; } 
    [ProtoMember(2)] 
    public int Value { get; set; } 
} 

static class Program 
{ 
    static void Main() 
    { 
     var obj = new MyObject 
     { 
      Name = "abc", 
      Value = 123, 
      Items = new List<MyOtherObject> 
      { 
       new MyOtherObject(), 
       new MyOtherObject(), 
       new MyOtherObject(), 
       new MyOtherObject(), 
      } 
     }; 
     using (var file = File.Create("foo.bin")) 
     { 
      Serializer.Serialize(file, obj); 
     } 
     MyObjectLite lite; 
     using (var file = File.OpenRead("foo.bin")) 
     { 
      lite= Serializer.Deserialize<MyObjectLite>(file); 
     } 
    } 
} 

但是,如果你不想要兩個不同的類型,和/或你不希望有添加屬性 - 可以得做到:

using ProtoBuf.Meta; 
using System.Collections.Generic; 
using System.IO; 

public class MyOtherObject { } 
public class MyObject 
{ 
    public string Name { get; set; } 
    public int Value { get; set; } 
    public IList<MyOtherObject> Items { get; set; } 
} 
static class Program 
{ 
    static readonly RuntimeTypeModel fatModel, liteModel; 
    static Program() 
    { 
     // configure models 
     fatModel = TypeModel.Create(); 
     fatModel.Add(typeof(MyOtherObject), false); 
     fatModel.Add(typeof(MyObject), false).Add("Name", "Value", "Items"); 
     liteModel = TypeModel.Create(); 
     liteModel.Add(typeof(MyOtherObject), false); 
     liteModel.Add(typeof(MyObject), false).Add("Name", "Value"); 
    } 
    static void Main() 
    { 
     var obj = new MyObject 
     { 
      Name = "abc", 
      Value = 123, 
      Items = new List<MyOtherObject> 
      { 
       new MyOtherObject(), 
       new MyOtherObject(), 
       new MyOtherObject(), 
       new MyOtherObject(), 
      } 
     }; 
     using (var file = File.Create("foo.bin")) 
     { 
      fatModel.Serialize(file, obj); 
     } 
     MyObject lite; 
     using (var file = File.OpenRead("foo.bin")) 
     { 
      lite = (MyObject)liteModel.Deserialize(
       file, null, typeof(MyObject)); 
     } 
    } 
} 
+1

+1。這很好,你可以從同一個字節數組中獲得兩個不同的模型。但有什麼需要時將「休息」反序列化爲'lite'的方法嗎?如果我正確理解這個解決方案,當你需要完整的對象時,它需要你拋棄'lite'並使用'fatModel'反序列化一個新的對象。 –

+0

因此,在你的第一個例子中,只要屬性名稱和類型與'ProtoMember'值相同,它不關心它反序列化的對象是什麼? –

+0

@Eren在某些情況下,*是*(protobuf是可合併的),但在一般情況下,我會說這只是錯誤的方法。 –

0

如何把NameValue成爲一個超類並分別序列化它們?

或者,您可以維護一個字典並將其序列化爲一個文件。

相關問題