我上课了。我想序列化并序列化包含该类对象的列表。我想使用二进制格式化程序。 这是我的班级:
[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);
}
}
我在序列化方面没有任何问题。但是对于反序列化,它只能反序列化第一个对象而不是所有对象。我该怎么办,请帮助我!
答案 0 :(得分:2)
从OP的另一封电子邮件中,获得了以下方法(我已经整理了一些,不多):
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
是可附加格式,并且顺序地序列化两个对象与同时序列化两个项目(列表)相同,例如:
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。事实上,protobuf-net在模型方面使这种情况变得毫不费力:
[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; }
}
和序列化/反序列化:
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();
}
}
最后,这2行的BinaryFormatter
数据是750字节;使用protobuf-net:40个字节。