问题描述
我已经开始转换Unity/iOS游戏,以通过Protobuf-net保存状态.看起来一切正常,直到我将此实例变量添加到GameState
I've started to convert our Unity/iOS game to save state with Protobuf-net. It looked like things were working OK, until I added this instance variable to GameState
[ProtoMember(10)]
public List<Unit> fUnits;
单位是
[ProtoContract]
[ProtoInclude(21, typeof(ArtilleryUnit))]
[ProtoInclude(22, typeof(CavalryArtilleryUnit))]
[ProtoInclude(23, typeof(CavalryUnit))]
[ProtoInclude(24, typeof(InfantryUnit))]
[Serializable]
public class Unit : IActionHandler
这是我序列化的第一个子类.我正在编写后立即通过反序列化来测试我的代码
This is the first subclass I've serialized. I'm testing my code by deserializing right after writing
using (Stream memoryStream = new MemoryStream()) {
byte[] data = System.Text.Encoding.UTF8.GetBytes(readText);
memoryStream.Write(data, 0, data.Length);
memoryStream.Position = 0;
WBTSSerializer deserializer = new WBTSSerializer();
testState = new GameState();
deserializer.Deserialize(memoryStream, testState, typeof(GameState));
}
我明白了
ProtoBuf.ProtoException: Invalid wire-type; this usually means you have over-written a file without truncating or setting the length; see http://stackoverflow.com/q/2152978/23354
at ProtoBuf.ProtoReader.SkipField () [0x00000] in <filename unknown>:0
at WBTSSerializer.Read (wbts.Unit , ProtoBuf.ProtoReader ) [0x00000] in <filename unknown>:0
at WBTSSerializer.Read (wbts.GameState , ProtoBuf.ProtoReader ) [0x00000] in <filename unknown>:0
at WBTSSerializer.Deserialize (Int32 , System.Object , ProtoBuf.ProtoReader ) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.TypeModel.DeserializeCore (ProtoBuf.ProtoReader reader, System.Type type, System.Object value, Boolean noAutoCreate) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream source, System.Object value, System.Type type, ProtoBuf.SerializationContext context) [0x00000] in <filename unknown>:0
at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream source, System.Object value, System.Type type) [0x00000] in <filename unknown>:0
at wbts.Game.SaveGame (System.String filename) [0x000c1] in /Users/david/Shenandoah/WBTS/wbts/wbts/Game.cs:620
不用说,我已经检查过覆盖(它是一个新文件).而且,如果我拿出ProtoMember(10)
,它将不会抛出.
Needless to say, I've checked for overwriting (it's a brand new file). And, if I take out the ProtoMember(10)
, it won't throw.
如果我删除ProtoInclude
行,则会收到有关子类的错误.而且,如果我在Unit
中取出ProtoMember
,它仍然会抛出.
If I take out the ProtoInclude
lines, I get an error about the subclasses. And, if I take out ProtoMember
within Unit
, it still throws.
如果有关系,我目前仅在Xamarin(在Mac OS X上,我是iOS开发人员)上运行它.但这只是为了简化测试,我设法用足够多的摇杆击中Protobuf-net,使其可以在iPad上运行.
If it matters, I am currently just running this from Xamarin (on Mac OS X — I'm an iOS developer). But that's just for ease of testing, I have managed to hit Protobuf-net with enough sticks to make it run on an iPad.
推荐答案
我的眼睛立即吸引到:
byte[] data = System.Text.Encoding.UTF8.GetBytes(readText);
Protobuf数据不是文本,也不是UTF-8(尽管巧合的是,字符串 inside protobuf数据是UTF-8)-因此对其进行解码"(错误的词,确实)通过UTF8
可以确保您破坏了数据.处理protobuf数据的首选方式是二进制(例如,byte[]
),就像处理图像数据等一样.但是,如果需要以文本形式存储或传输它,则Convert.ToBase64String
和Convert.FromBase64String
是在文本和二进制之间进行转换的适当机制.请参阅如何您可以通过多种方式搞乱IO吗?了解更多信息.
Protobuf data is not text, and is not UTF-8 (although strings inside protobuf data are UTF-8, by coincidence) - therefore "decoding" it (wrong word, really) via UTF8
will guarantee you corrupt data. The preferred way to deal with protobuf data is as binary - for example, a byte[]
- much like you would with image data etc. However, if you are required to store or transport it in a text form, then Convert.ToBase64String
and Convert.FromBase64String
are appropriate mechanisms to translate between text and binary. Please see the first section of How many ways can you mess up IO? for more information.
这篇关于使用Protobuf-net,使用List< Subclassable>获得关于未知导线类型的异常.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!