Как записать объект неизвестного типа в бинарный файл?

Ну, это в основном похоже на общий бинарный писатель... скажем, у вас есть объект, и вы не знаете, что это такое, но он у вас есть. Как вы записываете двоичные данные в двоичный файл, чтобы иметь возможность получить их позже?

Моя первоначальная идея, которую я не знаю, как сделать, заключалась в следующем:

  1. Как-нибудь выясните все члены объекта (может быть, отражение)
  2. Если члены не относятся к типам, доступным для записи BinaryWriter, повторите шаг 1 для члена.
  3. Сделайте заголовок, в котором указаны типы членов и то, как они собираются в объект (каким-то образом).
  4. Напишите заголовок
  5. Напишите все члены основного уровня

Я не знаю, как много использовать Reflection, поэтому я не уверен, как сделать большую часть вышеперечисленного. Однако это должно быть вполне выполнимо.

Как мне это сделать, если это возможно? Или как мне реализовать вышеизложенное?

bin

person user1319644    schedule 16.06.2013    source источник


Ответы (3)


Самый простой подход — использовать BinaryFormatter. Однако вы должны быть очень осторожны с любыми изменениями в ваших классах, если вы хотите загрузить экземпляры, сохраненные предыдущими версиями вашего приложения.

person Andrey Shchekin    schedule 16.06.2013

Сложный аспект заключается не в записи объектов, а в их считывании. Платформа .NET предоставляет различные методы сериализации и десериализации типов классов, которые должны автоматизировать процесс, но все встроенные методы, с которыми я знаком, имеют различные ограничения.

Основная проблема заключается в том, что .NET не делает различий между местом хранения, в котором содержится ссылка на объект с целью идентификации, и объектом, который используется другим кодом только для идентификации неизменяемые аспекты состояния объекта, отличные от идентификатора, или с целью инкапсуляции изменяемого состояния объекта. Не зная, что должно представлять поле, невозможно узнать, как его следует сериализовать или десериализовать. Например, предположим, что определенный тип имеет поле типа int[], которое содержит ссылку на одноэлементный массив, содержащий значение 23. Возможно, целью этого поля является хранение значения 23, или оно может заключается в том, что целью этого поля является идентификация массива, первый элемент которого должен увеличиваться каждый раз, когда что-то происходит. В первом сценарии сериализация должна записывать тот факт, что это массив из одного элемента, содержащий значение 23. Во втором сценарии, если сериализация вообще будет возможна, потребуется знать, что является значимым в массиве, к которому относится поле содержит ссылку.

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

person supercat    schedule 17.06.2013

Это может быть возможно с BinaryFormatter. Но подумайте о структуре объекта, в которой у вас есть много ваших unknown объектов, которые все ссылаются на общий объект. Если вы сериализуете все свои объекты unknown, вы получите столько копий общего объекта, сколько существует объектов unknown.

И может быть много полей объекта unknown, которые не имеют значения, поскольку они устанавливаются конструктором или другими классами, они могут находиться в несогласованном состоянии при десериализации.

Так что может быть не так сложно их сериализовать, но как вы хотите их десериализовать?

person thalm    schedule 17.06.2013