使用 ProtoBuf-net 快速获取序列化数据长度的方法?

发布于 2024-11-17 02:48:13 字数 1095 浏览 2 评论 0原文

假设我有一个 Person 类。它有一个可编辑的 Notes 属性。
我想将 Person 实例序列化到固定大小的缓冲区,因此注释不能无限长。
在用户界面中,我使用文本框让用户编辑注释。我想动态更新一个标签,说明您还可以写多少个字符。

这是我目前的实现,有没有更快的方法? (我正在使用 rs282)

    public Int32 GetSerializedLength()
    {
        Byte[] data;
        using (MemoryStream ms = new MemoryStream())
        {
            Serializer.SerializeWithLengthPrefix<Person>(ms, this, PrefixStyle.Base128);
            data = ms.ToArray();
        }
        using (MemoryStream ms = new MemoryStream(data))
        { 
            Int32 length = 0;
            if (Serializer.TryReadLengthPrefix(ms, PrefixStyle.Base128, out length))
                return length;
            else
                return -1;
        }
    }

编辑:我对序列化数据的内部长度和序列化数据的总长度感到困惑。
这是我的最终版本:

    private static MemoryStream _ms = new MemoryStream();
    public static Int64 GetSerializedLength(Person person)
    {
        if(null == person) return 0;
        _ms.SetLength(0);
        Serializer.Serialize<Person>(_ms, person);
        return _ms.Length;
    }

Let's say I have a Person class. It has an editable Notes property.
I want to serialize the Person instance to a fixed size buffer, thus the Notes cannot be infinite long.
In the UI, I use a TextBox to let user edit the notes. I want to dynamically update a label saying how many more characters you can write.

This is my current implementation, is there any faster method? (I'm using rs282)

    public Int32 GetSerializedLength()
    {
        Byte[] data;
        using (MemoryStream ms = new MemoryStream())
        {
            Serializer.SerializeWithLengthPrefix<Person>(ms, this, PrefixStyle.Base128);
            data = ms.ToArray();
        }
        using (MemoryStream ms = new MemoryStream(data))
        { 
            Int32 length = 0;
            if (Serializer.TryReadLengthPrefix(ms, PrefixStyle.Base128, out length))
                return length;
            else
                return -1;
        }
    }

EDIT: I'm confused about the internal lengh of the serialized data and the total length of the serialized data.
Here is my final version:

    private static MemoryStream _ms = new MemoryStream();
    public static Int64 GetSerializedLength(Person person)
    {
        if(null == person) return 0;
        _ms.SetLength(0);
        Serializer.Serialize<Person>(_ms, person);
        return _ms.Length;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情何以堪。 2024-11-24 02:48:13

通过编辑,听起来您想要长度而不序列化它(因为如果您想要长度序列化它,您只需序列化它并检查.长度)。

基本上,不 - 这是不可用的。我知道其他一些实现急切地构建这些数据,部分是因为它们一直在构建缓冲数据,而 protobuf-net 从对象图工作。

protobuf-net这样做 - 它通过在对象图上的单次传递期间发现来构建数据。您有什么特定的目的吗?东西总是可以添加的(尽管需要努力)。


关于您不希望过大的注释(字符串)字段的问题;作为健全性检查,请注意 protubuf 使用 UTF8 或字符串数​​据,因此个人我会这样做:

if(theText.Length > MAX || Encoding.UTF8.GetByteCount(theText) > MAX
       || GetSerializedLength(obj) > MAX)
{
        //
}

请注意,在明显的情况下我们已经以更便宜的方式检查了这一点

With the edit, it sounds like you want the length without serializing it (since if you want the length with serializing it, you'd just serialize it and check the .Length).

Basically, no - this isn't available. I know that some of the other implementations build this data eagerly, that is in part because they are constructing the buffered data all the time, where-as protobuf-net works from an object graph.

protobuf-net does not do this - it builds the data by discovery during a single pass over the object graph. Is there a specific purpose you have in mind? Things can always be added (with effort, though).


Re the issue of a notes (string) field that you don't want to be over-sized; as a sanity check, note that protubuf uses UTF8 or string data, so personally I would just do:

if(theText.Length > MAX || Encoding.UTF8.GetByteCount(theText) > MAX
       || GetSerializedLength(obj) > MAX)
{
        //
}

note we've checked this a bit more cheaply in the obvious cases

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文