2012-08-28 3 views
2

클래스가 있습니다. 나는 직렬화하고 그 클래스의 객체를 포함하는리스트를 직렬화하고 싶다. 바이너리 포맷터를 사용하고 싶습니다.리스트 바이너리 포맷터에 의한 직렬화와 직렬화 해제

[Serializable] 
public class Section :ISerializable 
{ 
    private double ClearCover; 
    private string SectionName; 

    private double Diameter; 

    public double Height; 
    private double Width; 

    private double InternalDiameter; 
    private double ExternalDiameter; 

    private double InternalHeight; 
    private double ExternalHeight; 
    private double InternalWidth; 
    private double ExternalWidth; 

    private double WebWidth; 
    private double FlangeWidth; 
    private double FlangeThickness; 



    public double clearCover 
    { 
     get { return ClearCover; } 
     set { ClearCover = value; } 
    } 
    public string sectionName 
    { 
     get{return SectionName;} 
     set{SectionName=value;} 
    } 

    public double diameter 
    { 
     get { return Diameter; } 
     set { Diameter = value; } 
    } 

    public double height 
    { 
     set { Height = value; } 
     get { return Height; } 
    } 
    public double width 
    { 
     set { Width = value; } 
     get { return Width; } 
    } 

    public double internalDiameter 
    { 
     set { InternalDiameter = value; } 
     get { return InternalDiameter; } 
    } 
    public double externalDiameter 
    { 
     set { ExternalDiameter = value; } 
     get { return ExternalDiameter; } 
    } 

    public double internalHeight 
    { 
     set { InternalHeight = value; } 
     get { return InternalHeight; } 
    } 
    public double externalHeight 
    { 
     set { ExternalHeight = value; } 
     get { return ExternalHeight; } 
    } 
    public double internalWidth 
    { 
     set { InternalWidth = value; } 
     get { return InternalWidth; } 
    } 
    public double externalWidth 
    { 
     set { ExternalWidth = value; } 
     get { return ExternalWidth; } 
    } 

    public double flangeWidth 
    { 
     set { FlangeWidth = value; } 
     get { return FlangeWidth; } 
    } 
    public double flangeThickness 
    { 
     set { FlangeThickness = value; } 
     get { return FlangeThickness; } 
    } 
    public double webWidth 
    { 
     set { WebWidth = value; } 
     get { return WebWidth; } 
    } 




    public Section() { } 

    protected Section(SerializationInfo info, StreamingContext context) 
    { 
     sectionName = info.GetString("Section Name"); 
     clearCover = info.GetDouble("Clear Cover"); 

     diameter = info.GetDouble("Diameter"); 

     //internalDiameter = info.GetDouble("Internal Diameter"); 
     //externalDiameter = info.GetDouble("External Diameter"); 


     height = info.GetDouble("Height"); 
     width = info.GetDouble("Width"); 



     internalHeight = info.GetDouble("Internal Height"); 
     externalHeight = info.GetDouble("External Height"); 
     internalWidth = info.GetDouble("Internal Width"); 
     externalWidth = info.GetDouble("External Width"); 

     flangeWidth = info.GetDouble("Flange Width"); 
     flangeThickness = info.GetDouble("Flange Thickness"); 
     webWidth = info.GetDouble("Web Width"); 



    } 

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("Section Name", sectionName); 
     info.AddValue("Clear Cover", clearCover); 

     info.AddValue("Diameter",diameter); 

     //info.AddValue("Internal Diameter", internalDiameter); 
     //info.AddValue("External Diameter", externalDiameter); 

     info.AddValue("Height",height); 
     info.AddValue("Width",width); 

     info.AddValue("Internal Height",internalHeight); 
     info.AddValue("External Height",externalHeight); 
     info.AddValue("Internal Width",internalWidth); 
     info.AddValue("External Width",externalWidth); 

     info.AddValue("Flange Width",flangeWidth); 
     info.AddValue("Flange Thickness", flangeThickness); 
     info.AddValue("Web Width", webWidth); 


    } 


} 

내가 직렬화에 문제가 없습니다 : 이 내 클래스입니다. 그러나 비 직렬화의 경우, 모든 객체가 아닌 첫 번째 객체를 비 직렬화 할 수 있습니다. 어떻게해야합니까, 제발 도와주세요! 영업에서 별도의 이메일에서

답변

2

, 다음과 같은 방법을 얻을 수 있었다 (나는별로, 그들에게 조금 정돈 한) :

static void Serialize(object obj, string filename) 
{ 
    using (FileStream streamOut = new FileStream(filename, FileMode.Append)) 
    { 
     BinaryFormatter formatter = new BinaryFormatter(); 
     formatter.Serialize(streamOut, obj); 
    } 
} 


public static List<Section> DeserializeList(string filename) 
{ 
    using (FileStream streamIn = File.OpenRead(filename)) 
    { 
     BinaryFormatter formatter = new BinaryFormatter(); 
     return (List<Section>) formatter.Deserialize(streamIn); 
    } 
} 

여기서 중요한 관찰은 BinaryFormatter은을이라고 가정된다는 것이다 추가 가능한 포맷 순차적 두 객체를 직렬화하는 것은, 예를 들면, 동시에 2 개 항목 (리스트)를 직렬화과 동일 함 :

if(File.Exists("foo.bin")) File.Delete("foo.bin"); // start afresh 
Serialize(new Section { Diameter = 1.2, ClearCover = 3.4 }, "foo.bin"); 
Serialize(new Section { Diameter = 5.6, ClearCover = 7.8 }, "foo.bin"); 

var clone = DeserializeList("foo.bin"); 

그러나, 단순히 케이스 아니다. 이 방법의 항목을 역 직렬화하기 위해, 우리는 같은 것을해야 할 것 :

public static List<Section> DeserializeList(string filename) 
{ 
    using (FileStream streamIn = File.OpenRead(filename)) 
    { 
     List<Section> list = new List<Section>(); 
     BinaryFormatter formatter = new BinaryFormatter(); 
     while(streamIn.Position != streamIn.Length) 
     { 
      list.Add((Section) formatter.Deserialize(streamIn)); 
     } 
     return list; 
    } 
} 

을하는 것이 조금 애 태우게 - 아니 적어도 그것은 (모든 스트림에 .Length을 적용 할 수없는, 심지어 .Position은 보편적으로 사용할 수 없습니다 수 있기 때문에).

위의 으로 작동해야하지만 protobuf와 같은 추가 형식을 사용하는 것이 좋습니다.

[ProtoContract] 
public class Section 
{ 
    [ProtoMember(1)] public double ClearCover { get; set; } 
    [ProtoMember(2)] public string SectionName { get; set; } 
    [ProtoMember(3)] public double Diameter { get; set; } 
    [ProtoMember(4)] public double Height { get; set; } 
    [ProtoMember(5)] public double Width { get; set; } 
    [ProtoMember(6)] public double InternalDiameter { get; set; } 
    [ProtoMember(7)] public double ExternalDiameter { get; set; } 
    [ProtoMember(8)] public double InternalHeight { get; set; } 
    [ProtoMember(9)] public double ExternalHeight { get; set; } 
    [ProtoMember(10)] public double InternalWidth { get; set; } 
    [ProtoMember(11)] public double ExternalWidth { get; set; } 
    [ProtoMember(12)] public double FlangeWidth { get; set; } 
    [ProtoMember(13)] public double FlangeThickness { get; set; } 
    [ProtoMember(14)] public double WebWidth { get; set; } 
} 

및 직렬화/역 직렬화 : 사실, protobuf - 그물 모델의 측면에서 모두,이 시나리오는 노력한다, 그 2 행에 대한 BinaryFormatter 데이터는 750 바이트 마지막으로

static void Main() 
{ 
    if (File.Exists("foo.bin")) File.Delete("foo.bin"); // start afresh 

    Serialize(new Section { Diameter = 1.2, ClearCover = 3.4 }, "foo.bin"); 
    Serialize(new Section { Diameter = 5.6, ClearCover = 7.8 }, "foo.bin"); 

    var clone = DeserializeList("foo.bin"); 
} 
static void Serialize(object obj, string filename) 
{ 
    using (FileStream streamOut = new FileStream(filename, FileMode.Append)) 
    { 
     Serializer.NonGeneric.SerializeWithLengthPrefix(
      streamOut, obj, PrefixStyle.Base128, Serializer.ListItemTag); 
    } 
} 


public static List<Section> DeserializeList(string filename) 
{ 
    using (FileStream streamIn = File.OpenRead(filename)) 
    { 
     return Serializer.DeserializeItems<Section>(
      streamIn, PrefixStyle.Base128, Serializer.ListItemTag).ToList(); 
    } 
} 

이었다 ; protobuf-net : 40 바이트.

+0

고마워요 :) –

+0

첫 번째 부분 (바이너리 포맷터 사용)에서는이 오류가 발생합니다. 'System.Collections.Generic.List'1 [KSU.Section] 유형의 개체를'KSU '형식으로 캐스팅 할 수 없습니다. .섹션'. 그것은 말이되지 않습니다. 당신이 쓴 코드에 따라, 그것은 Section Type 객체에 아무 것도 던지지 않았습니다. –

+0

방금 ​​실수로 실수를했습니다. 작동, 감사합니다 :) –

관련 문제