I want to serialize List<ArchiveData>
but it nearly always fail. Protobuff throw following exception:
Invalid wire-type; this usually means you have over-written a file without truncating or setting the length; see Using Protobuf-net, I suddenly got an exception about an unknown wire-type
I have read the post but still can not find a solution. How can i serialize and deserialize this?
My Class and Struct:
[Serializable, ProtoContract(Name = @"Archive"), ProtoInclude(1, typeof(List<ArchiveData>))]
public partial class Archive : IExtensible
{
[ProtoMember(1, IsRequired = true, OverwriteList = true, Name = @"data", DataFormat = DataFormat.Default)]
public List<ArchiveData> data { get; set; }
public Archive()
{
data = new List<ArchiveForm.ArchiveData>();
}
private IExtension extensionObject;
IExtension IExtensible.GetExtensionObject(bool createIfMissing)
{
return Extensible.GetExtensionObject(ref extensionObject, createIfMissing);
}
}
public struct ArchiveData
{
[ProtoMember(1, IsRequired = false, OverwriteList = true, Name = @"sourcefolder", DataFormat = DataFormat.Default)]
[global::System.ComponentModel.DefaultValue("")]
public string sourcefolder { get; set; }
[ProtoMember(2, IsRequired = false, OverwriteList = true, Name = @"destinationfolder", DataFormat = DataFormat.Default)]
[global::System.ComponentModel.DefaultValue("")]
public string destinationfolder { get; set; }
[ProtoMember(3, IsRequired = false, OverwriteList = true, Name = @"period", DataFormat = DataFormat.FixedSize)]
[global::System.ComponentModel.DefaultValue((int)0)]
public int period { get; set; }
public ArchiveData(string sfolder = "", string dfolder = "", int priod = 0)
{
sourcefolder = sfolder;
destinationfolder = dfolder;
period = priod;
}
}
I serialize that with following method:
public static void Refresh(ref Archive arc)
{
if (File.Exists(probuffile))
{
using (var fs = File.OpenRead(probuffile))
{
arc = Serializer.Deserialize<Archive>(fs);
}
}
}
And i deserialize that with following method:
public static void Update(Archive arc)
{
using (var fs = File.Create(probuffile))
{
Serializer.Serialize<Archive>(fs, arc);
fs.SetLength(fs.Position);
}
}
And i use it:
Archive archive = new Archive();
//Add some ArchiveData.
Refresh(ref archive);
------------------------------Edit------------------------------
This section has been added for more information. When I use SerializeWithLengthPrefix / DeserializeWithLengthPrefix function like following code, it work properly every time for the first class that i use the Deserialize function. But it return null for the second class that i use the Deserialize function.
[Serializable, ProtoContract(Name = @"OptionData")]
public class OptionData : IExtensible
{
[ProtoMember(1, IsRequired = false, OverwriteList = true, Name = @"StartWithWindows", DataFormat = DataFormat.Default)]
[DefaultValue(false)]
public bool StartWithWindows { get; set; }
[ProtoMember(2, IsRequired = false, OverwriteList = true, Name = @"AutoBackup", DataFormat = DataFormat.Default)]
[DefaultValue(false)]
public bool AutoBackup { get; set; }
[ProtoMember(3, IsRequired = false, OverwriteList = true, Name = @"Speed", DataFormat = DataFormat.FixedSize)]
[DefaultValue((int)0)]
public int Speed { get; set; }
private IExtension extensionObject;
IExtension IExtensible.GetExtensionObject(bool createIfMissing)
{
return Extensible.GetExtensionObject(ref extensionObject, createIfMissing);
}
}
public static void Update(OptionData op)
{
using (var fs = File.Create(probuffile))
{
Serializer.SerializeWithLengthPrefix(fs, op, PrefixStyle.Base128, 3);
}
}
public static void Update(Archive arc)
{
using (var fs = File.Create(probuffile))
{
Serializer.SerializeWithLengthPrefix<Archive>(fs, arc, PrefixStyle.Base128, 2);
}
}
public static void Refresh(ref OptionData op)
{
if (File.Exists(probuffile))
{
using (var fs = File.OpenRead(probuffile))
{
op = Serializer.DeserializeWithLengthPrefix<OptionData>(fs, PrefixStyle.Base128, 3);
}
}
}
public static void Refresh(ref Archive arc)
{
if (File.Exists(probuffile))
{
using (var fs = File.OpenRead(probuffile))
{
arc = Serializer.DeserializeWithLengthPrefix<Archive>(fs, PrefixStyle.Base128, 2);
}
}
}