Быстрый способ получить длину сериализованных данных с помощью ProtoBuf-net? - PullRequest
2 голосов
/ 25 июня 2011

Допустим, у меня есть класс Person. Имеет редактируемое свойство Notes.
Я хочу сериализовать экземпляр Person в буфер фиксированного размера, поэтому примечания не могут быть бесконечно длинными.
В пользовательском интерфейсе я использую TextBox, чтобы позволить пользователю редактировать заметки. Я хочу динамически обновлять метку, говоря, сколько еще символов вы можете написать.

Это моя текущая реализация, есть ли более быстрый метод? (Я использую 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;
    }

1 Ответ

1 голос
/ 25 июня 2011

При редактировании звучит так, как будто вы хотите, чтобы длина без сериализовала ее (поскольку, если вы хотите, чтобы длина с сериализовала ее, вы просто сериализовали бы ее и проверяли .Length).

По сути, нет - это недоступно.Я знаю, что некоторые из других реализаций с удовольствием строят эти данные, то есть в части , потому что они все время строят буферизованные данные, где protobuf-net работает из графа объектов.

protobuf-net не делает это - он строит данные путем обнаружения в течение одного прохода по графу объектов.Есть ли у вас какая-то конкретная цель?Вещи всегда можно добавить (хотя и с усилием).


По вопросу о поле примечаний (строки), которое вы не хотите, чтобы его размер был слишком большим;в качестве проверки работоспособности обратите внимание, что protubuf использует UTF8 или строковые данные, поэтому лично Я бы просто сделал:

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

обратите внимание, что мы проверили это немного дешевле в очевидных случаях

...