C# 使用Protobuf net恢复损坏的文件序列化

C# 使用Protobuf net恢复损坏的文件序列化,c#,file-io,protobuf-net,C#,File Io,Protobuf Net,我猜想,当我的应用程序正在更新一个文件时,机器的电源被切断了。当重新打开并且我的应用程序启动时,它试图反序列化文件。对序列化程序.反序列化的调用没有失败,但结果对象的每个属性都有默认值 我的文件更新/保存: using (FileStream theStream = File.Open(fileName + "_tmp", FileMode.Create)) { ProtoBuf.Serializer.Serialize<MyObject>(theStream, inObje

我猜想,当我的应用程序正在更新一个文件时,机器的电源被切断了。当重新打开并且我的应用程序启动时,它试图反序列化文件。对序列化程序.反序列化的调用没有失败,但结果对象的每个属性都有默认值

我的文件更新/保存:

using (FileStream theStream = File.Open(fileName + "_tmp", FileMode.Create)) {
    ProtoBuf.Serializer.Serialize<MyObject>(theStream, inObjectToSerialize);
}
File.Copy(fileName + "_tmp", fileName, true);
使用(FileStream theStream=File.Open(fileName+“_tmp”,FileMode.Create)){
ProtoBuf.Serializer.Serialize(流,inObjectToSerialize);
}
File.Copy(fileName+“_tmp”,fileName,true);
没有tmp文件,只有主文件。文件的大小不是零,这让我相信信息是完整的。有没有办法恢复这些数据

更新:


我在ProtoReader上尝试了Marc的建议,问题中的文件导致在
reader.ReadFieldHeader()上抛出异常。ProtoException的内容是:“源数据中的无效字段:0”

这里没有什么可供我讨论的。。。我想简短的版本应该是:它取决于文件中剩下的内容

您可以做的一件事是浏览文件,看看有什么:

using (var input = File.OpenRead(path))
using (var reader = new ProtoReader(input, RuntimeTypeModel.Default, null))
{
    while (reader.ReadFieldHeader() > 0)
    {
        Console.WriteLine("offset {0}, field {1}, type {2}",
            reader.Position, reader.FieldNumber, reader.WireType);
        reader.SkipField();
    }
}
这至少可以让您看到当前正在处理多少数据


如果您知道某些字段的布局(即“字段3是字符串,字段7是子对象等”),则可以使输出更详细。

我尝试了您的建议,但发现我一直在使用r282。我似乎已经有一段时间没有遇到protobuf网络问题了。所以我下载了r580并试着把它放进去。现在,当我尝试反序列化以前成功的文件时,我得到了“NotSupportedException:具有继承的结构或类中不支持IEExtensible”,并且使用不同的序列化对象,我得到了“InvalidOperationException:没有为类型定义序列化程序:System.Net.IP.Address”。现在我的情况比以前更糟了。@DanVogel
IPAddress
可以通过
var model=TypeModel.Create()启用;model.AllowParseableTypes=true
并使用
model.Serialize(…)
etc而不是
Serializer.Serialize
。添加了
ieextensible
警告,以解决可能也会影响r282的问题-我可能会采取一些措施让它过去。然而!所有这些都是没有意义的:这里首先要评估的是文件的状态,仅仅使用
ProtoReader
本身不会引起您所描述的问题。我想我已经超越了自己。我已经运行了你关于ProtoReader的建议,并更新了我的原始帖子。这是(编辑)马上吗?或者,如果没有:有多远?如果接近末尾,可以使用构造函数限制读取的量。档案有多大?如果您能够共享该文件,我可能可以使用该格式的知识来恢复,而不仅仅是“直到它爆炸”,但我不能做出承诺。@MarcGravel它会立即发生。我会把一个样本项目放在一起,这样你就可以看到我在做什么。