我试图将列表中的点数据保存到protobuf.net创建的二进制文件中.虽然我本身没有遇到麻烦,但我也试图以一种在文本编辑器中不易查看的格式保存数据.默认情况下,将List of Point结构保存到
[global::ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"BufPoints", DataFormat = global::ProtoBuf.DataFormat.Default)] private List<Point> BufPoints { get { return this.Points; } set { this.Points = value; } }
我已经尝试创建自己的类来保存x和y双数据,但是我的例程的一部分涉及数据的深度克隆,并且在执行此克隆时似乎丢失了值.
[global::ProtoBuf.ProtoMember(1, IsRequired = false, Name = @"EncodedPoints", DataFormat = global::ProtoBuf.DataFormat.Default)] private List<Utils.PointConverter> EncodedPoints { get { List<Utils.PointConverter> temp = new List<Utils.PointConverter>(); if (Points != null) { foreach (Point p in this.Points) { temp.Add(new Utils.PointConverter(p)); } } return temp; } set { if (value != null) { this.Points = new List<Point>(); foreach (Utils.PointConverter pc in value) { this.Points.Add(pc.GetPoint()); } } } }
PointsConverter类如下:
[global::System.Serializable, global::ProtoBuf.ProtoContract(Name = @"PointConverter")] class PointConverter { [global::ProtoBuf.ProtoMember(1, IsRequired = true, Name = @"X", DataFormat = global::ProtoBuf.DataFormat.Default)] public double X; [global::ProtoBuf.ProtoMember(2, IsRequired = true, Name = @"Y", DataFormat = global::ProtoBuf.DataFormat.Default)] public double Y; public PointConverter(System.Windows.Point point) { this.X = point.X; this.Y = point.Y; } public PointConverter() { } public System.Windows.Point GetPoint() { return new System.Windows.Point(X, Y); } }
我不确定为什么在深度克隆过程中值会丢失.有没有办法以非ascii格式另外保存数据或者使用深度克隆处理我的问题?
首先,protobuf在任何时候都不是ASCII(虽然字符串值存储为UTF-8,对于没有重音的拉丁字符,它通常看起来像ASCII) – 我无法评论你在没有上下文的情况下看到的内容,但是序列化也不是加密.使用二进制格式可能会使某人阅读/编辑内容变得尴尬,但不要将其用作安全检查的一部分.至于代码:我认为你过于复杂化了.实际上,对于System.Drawing.Point和System.Windows.Point,代码非常接近于自动计算映射作为“自动元组”处理的一部分.但不完全!但是我们可以通过在你的app-startup中添加一行配置调整来简单地教育它,告诉它通过将.X存储为字段1来串行化Point,并将.Y存储为字段2.这只是:
// either or both; whatever you need model.Add(typeof(System.Windows.Point), false).Add("X", "Y"); model.Add(typeof(System.Drawing.Point), false).Add("X", "Y");
或者如果您使用的是默认模型实例(即Serializer.*方法):
// either or both; whatever you need RuntimeTypeModel.Default.Add(typeof(System.Windows.Point), false).Add("X", "Y"); RuntimeTypeModel.Default.Add(typeof(System.Drawing.Point), false).Add("X", "Y");
而且……就是这样!这就是你所需要的一切. Point或List的成员< Point>或者Point []现在应该正确序列化和反序列化.