c# - 从 protobuf-net 读取时跳过数据

标签 c# protobuf-net

我有一个文件,其中有 n 个对象实例被序列化并存储在其中。 在某些情况下,我需要跳过存储的记录并以 k 2k 3k ... n 序列读取,而不是正常的 1 2 3 ... n 序列。由于这些实例的长度不同,我编写了这段代码来跳过记录,但它抛出了无效的线类型异常。 (异常有一个指向 this question 的链接,但没有帮助)

这只是一个简单的错误还是我以错误的方式这样做?

long position = stream.Position;
int length = 0;
for (int i = 0; i < skipRate; ++i)
{
    Serializer.TryReadLengthPrefix(stream, PrefixStyle.Fixed32, out length);
    position += length;
    stream.Position = position;
    Console.WriteLine("Skipped " + length + " bytes");
}

MYCLASS retval = Serializer.DeserializeWithLengthPrefix<MYCLASS>(stream, PrefixStyle.Fixed32, 1);

编辑:

long position = stream.Position;
int length;
for (int i = 0; i < skipRate; ++i)
{
    Serializer.TryReadLengthPrefix(stream, PrefixStyle.Fixed32, out length);
    length += (int)(stream.Position - position); // add number of bytes that TryReadLengthPrefix moves stream

    stream.Position = position; // Rewind
    Serializer.DeserializeWithLengthPrefix<SimulationOutputData>(stream, PrefixStyle.Fixed32, 1);
    Console.WriteLine("Try read returns " + length + ", but deserialize goes on " + (stream.Position-position));
}

输出:

Try read returns 1209, but deserialize goes on 1209
Try read returns 1186, but deserialize goes on 1186
Try read returns 1186, but deserialize goes on 1186
Try read returns 1186, but deserialize goes on 1186
Try read returns 1186, but deserialize goes on 1186
Try read returns 1209, but deserialize goes on 1209
Try read returns 1167, but deserialize goes on 1167
.
.
.

这段代码有效(为什么?!!有什么区别?):

Serializer.TryReadLengthPrefix(stream, PrefixStyle.Fixed32, out length);
length += (int)(stream.Position - position);
stream.Position = position;
position += length;
stream.Position = position;

最佳答案

athabaska(评论)有其要点。您的 position 增量不考虑标题。一个简洁的实现可能是:

for (int i = 0; i < skipRate; ++i)
{
    int length;
    if(!Serializer.TryReadLengthPrefix(stream, PrefixStyle.Fixed32, out length))
    {
        throw new EndOfStreamException(); // not enough records
    }
    s.Seek(length, SeekOrigin.Current);
}

MYCLASS retval = Serializer.DeserializeWithLengthPrefix<MYCLASS>(
    stream, PrefixStyle.Fixed32, 0);

关于c# - 从 protobuf-net 读取时跳过数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21449430/

相关文章:

c# - Protobuf-net 似乎是对值类型进行包装。事实是这样吗?

c# - 在另一个线程中填充的排序列表

c# - 如何使用 SQL Command Builder 和 SQL Data Apdater

c# - 如果在 ListView 中未选择任何项目,如何禁用按钮

.net - 在 Silverlight 中使用自定义 WCF 序列化器

c# - Protobuf net 未被告知序列化 System.Object 但仍然出现错误 : No serializer defined for type: System. 对象

c# - 为什么运算符比方法调用慢得多? (结构仅在较旧的 JIT 上较慢)

c# - ASP.NET MVC - [Bind(Exclude = "Id")] 的替代方法

c# - 为什么我无法使用 protobuf-net 从二进制数据中读取 VarInt 字段

c# - 跨平台 Protobuf 序列化