List<ArchiveData>
をシリアライズしたいですが、ほとんどいつも失敗します。 Protobuff throw例外:protobufでList <class object>をシリアライズ/デシリアライズする方法は?
ワイヤタイプが無効です。これは通常、長さを切り捨てたり設定したりせずにファイル を上書きしたことを意味します。 Using Protobuf-net, I suddenly got an exception about an unknown wire-type
私は投稿を読みましたが、解決策を見つけることができません。どのように私はシリアル化し、これを逆シリアル化することができますか?
私のクラスと構造体:
[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;
}
}
私は次の方法であることをシリアライズ:
public static void Refresh(ref Archive arc)
{
if (File.Exists(probuffile))
{
using (var fs = File.OpenRead(probuffile))
{
arc = Serializer.Deserialize<Archive>(fs);
}
}
}
、私は次のような方法であることデシリアライズ:
public static void Update(Archive arc)
{
using (var fs = File.Create(probuffile))
{
Serializer.Serialize<Archive>(fs, arc);
fs.SetLength(fs.Position);
}
}
、私はそれを使用します。
Archive archive = new Archive();
//Add some ArchiveData.
Refresh(ref archive);
------------------------------編集--------------- ---------------
このセクションは、追加情報として追加されました。次のコードのようなSerializeWithLengthPrefix/DeserializeWithLengthPrefix関数を使用すると、Deserialize関数を使用するファーストクラスのたびに正しく動作します。しかし、それは私がDeserialize関数を使用する2番目のクラスのnullを返します。
[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);
}
}
}
後に長さを設定して問題ありません - 私は、本当の問題はここでは実際には「(デ)シリアライズであると仮定することができますオブジェクト、ワイヤタイプのエラーを取得しています "? –
申し訳ありません。私の悪い。私はクラスを書くのを忘れた。 –
編集:それらは同じファイルにありますか?または別のファイルですか?同じファイルから連続する2つのものを読みたい場合は、単一の 'File.OpenRead'セッションでそれらを連続して読み込む必要があります。それ以外の場合は、 'File.OpenRead'を呼び出すたびにファイルの先頭に戻り、間違ったデータを読み込みます。あなたは 'Update'と' Refresh'がどのように使われているかを示していないので、私は100%確実ではありません。繰り返しますが、私の答えのように、実際に問題が発生していることを示す**完全実行可能な**コード( 'Main()'メソッドなど)を投稿するのが最善の方法です。 –