Как проанализировать содержание двоичного потока сериализации?

Я использую двоичную сериализацию (BinaryFormatter) в качестве временного механизма, чтобы хранить информацию состояния в файле для относительно сложного (игра) структура объекта; файлы выходят намного больше, чем я ожидаю, и моя структура данных включает рекурсивные ссылки - таким образом, я задаюсь вопросом, хранит ли BinaryFormatter на самом деле несколько копий тех же объектов, или является ли мое основное "количество объектов и значений, которые я должен иметь" arithmentic, неосновным путем, или куда еще чрезмерный размер прибывает из.

При поиске на переполнении стека я смог найти спецификацию для двоичного формата дистанционной работы Microsoft: http://msdn.microsoft.com/en-us/library/cc236844 (Протестант 10) .aspx

То, что я не могу найти, является любым существующим средством просмотра, которое позволяет Вам "посмотреть" в содержание binaryformatter выходного файла - получают числа объектов и общие байты для различных типов объектов в файле, и т.д.;

Я чувствую, что это должно быть моим "google-fu", приводящим меня к сбою (что мало я имею) - кто-либо может помочь? Это, должно быть, было сделано прежде, правильно??


ОБНОВЛЕНИЕ: Я не мог найти его и не получил ответов, таким образом, я поместил что-то относительно быстрое вместе (свяжитесь с загружаемым проектом ниже); я могу подтвердить, что BinaryFormatter не хранит несколько копий того же объекта, но он действительно печатает довольно много метаданных к потоку. Если Вы нуждаетесь в эффективном устройстве хранения данных, создаете Ваши собственные методы сериализации.

33
задан Tao 20 June 2010 в 12:54
поделиться

3 ответа

Наше приложение обрабатывает большие объемы данных. Это может занять до 1-2 ГБ ОЗУ, как и ваша игра. Мы столкнулись с одной и той же проблемой «хранения нескольких копий одних и тех же объектов». Также двоичная сериализация хранит слишком много метаданных. Когда он был впервые реализован, сериализованный файл занимал около 1-2 ГБ. Сейчас удалось уменьшить значение - 50-100 МБ. Что мы сделали.

Короткий ответ - не используйте двоичную сериализацию .Net, создайте свой собственный механизм двоичной сериализации. ​​У нас есть собственный класс BinaryFormatter и интерфейс ISerializable (с двумя методами Serialize, Deserialize).

Один и тот же объект не следует сериализовать более одного раза. Сохраняем уникальный ID и восстанавливаем объект из кеша.

Я могу поделиться кодом, если вы спросите.

РЕДАКТИРОВАТЬ: Кажется, вы правы. См. Следующий код - он доказывает, что я был неправ.

[Serializable]
public class Item
{
    public string Data { get; set; }
}

[Serializable]
public class ItemHolder
{
    public Item Item1 { get; set; }

    public Item Item2 { get; set; }
}

public class Program
{
    public static void Main(params string[] args)
    {
        {
            Item item0 = new Item() { Data = "0000000000" };
            ItemHolder holderOneInstance = new ItemHolder() { Item1 = item0, Item2 = item0 };

            var fs0 = File.Create("temp-file0.txt");
            var formatter0 = new BinaryFormatter();
            formatter0.Serialize(fs0, holderOneInstance);
            fs0.Close();
            Console.WriteLine("One instance: " + new FileInfo(fs0.Name).Length); // 335
            //File.Delete(fs0.Name);
        }

        {
            Item item1 = new Item() { Data = "1111111111" };
            Item item2 = new Item() { Data = "2222222222" };
            ItemHolder holderTwoInstances = new ItemHolder() { Item1 = item1, Item2 = item2 };

            var fs1 = File.Create("temp-file1.txt");
            var formatter1 = new BinaryFormatter();
            formatter1.Serialize(fs1, holderTwoInstances);
            fs1.Close();
            Console.WriteLine("Two instances: " + new FileInfo(fs1.Name).Length); // 360
            //File.Delete(fs1.Name);
        }
    }
}

Похоже, BinaryFormatter использует object.Equals для поиска одинаковых объектов.

Вы когда-нибудь заглядывали внутрь сгенерированных файлов? Если вы откроете «temp-file0.txt» и «temp-file1.txt» из примера кода, вы увидите, что в нем много метаданных. Вот почему я рекомендовал вам создать свой собственный механизм сериализации.

Извините за совместное использование.

5
ответ дан 27 November 2019 в 17:35
поделиться

Возможно, вы могли бы запустить свою программу в режиме отладки и попробовать добавить контрольную точку.

Если это невозможно из-за размера игры или других зависимостей, вы всегда можете создать простое / небольшое приложение, которое включает код десериализации, и посмотреть из режима отладки.

0
ответ дан 27 November 2019 в 17:35
поделиться

??????? ???? ? ???, ??? ??? ? ???????? ????? ??????????? ??????????? ??????????? ??????? ??????????????/????????????, ????? ????? ???????????? ?????? ? ???????? ??????? ????? ?????????? ????? (?? ??????).

?????? ? ????? ??????, ??? ?????????? ? ??????, ??????? ? ??????? (????????????) ??????? ?????, ??????? ?????? ??, ??? ? ?????:

  • ??????????? ???? ???? ? ??????, ???????? ????????? ???? ????????, ???????? ? ???????
  • ????? ?????????? ??????? ??????? ?????? ????, ??? ?? ????? ? ??????, ???????? ? ????? ??????? ? ??????

??? ???? ???????????? ??????? ????????? ??? ???-?? ?? ?????? ?????, ????????, codeproject, ??????? ? ?????? ??????? ?????? ? zip-????? ?? ???? ???-?????: http://www.architectshack.com/BinarySerializationAnalysis.ashx

? ???? ?????????? ?????? ?????????, ??? ???????? ???? ???????:

  • BinaryFormatter ????? ??????????? (??? ????????, ? ?????? ?? ??????? ?????????)
  • ? ???? ????????????? ???? ???????? ? ???? ??????, ?????????, ??? ? ?????? ???????, ??????? ??? ?? ?????

???????, ??? ?????-?????? ??????? ????-??????!


??????????: ?? ???? ???????? ?? ???? ?? ?????? ???????? ? ???????? ?????, ????? ?? ???????? ???????? ??????, ????? ???????? ??????(?) ???????? "??????????" ????????. ?????? ??? ??????????, ? ? ?????????????? ???????, ????? ??????????? ??? ?? GitHub ? ???? ??? (???????????, BSD) ????????.

7
ответ дан 27 November 2019 в 17:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: