2015-07-02 5 views
6

Я пытаюсь сделать переход от C к C#, и у меня есть несколько вопросов о сохранении объектов в файлах и сериализации.Сохранение объектов/сериализация

В C, если вы хотите сохранить структуру данных, меня научили тому, что сохранение его в текстовом формате в виде строки часто не нужно, а двоичный файл, который существует в качестве моментального снимка памяти, часто лучше, потому что он не " t требуется кодирование/декодирование и сопоставление строк с полями. В C# подход кажется другим, он преобразует поля объекта отдельно в строку или какой-либо другой формат, а затем восстанавливает объект, когда это необходимо. Я не уверен, как работает двоичная сериализация, но я думаю, что это похоже на преобразование данных в какой-то формат и не существует как чистый неформатированный снимок памяти.

Почему метод «моментального снимка памяти» без кодирования/декодирования, не используемого в C#? Единственная причина, по которой я могу думать, это совместимость с другими кодами и средами, и, возможно, это связано со сложностью объектов против обычных структур.

+0

Что делать, если объект имеет сложные свойства, а не только типы значений; то каждая «часть» объекта будет храниться в другой ячейке памяти; также эти объекты могут включать в себя другие объекты. Просто простая догадка, но было бы очень сложно выполнить такую ​​логику для сохранения объектов. – daryal

+0

Одним из значительных сокращений затрат и преимуществ для производительности является абстракция памяти .NET и аппаратное обеспечение в целом. Если вам необходимо сохранить основные требования, пусть структура обрабатывает тяжелую работу (как это часто бывает) и маркирует ваш класс с помощью [Serializable] и использует классы, доступные в System.Runtime.Serialization.Formatters.Binary. – Michael

ответ

2

В C# у вас нет доступа к макету памяти объекта. Вы не можете получить снимок памяти для объекта или создать объект из моментального снимка. Фактически, у вас даже нет точек (да, у вас их есть в небезопасном коде, но вы редко когда-либо пишете небезопасный код).

Даже если у вас есть доступ к памяти, используемой объектом, она может не сохраниться, если ее сохранить на диск, а затем перезагрузить. Если вы обновляете среду .NET, вы можете получить лучший оптимизатор, который решает изменить порядок полей объекта по-разному или использовать другое выравнивание памяти.

Итак, короче - нет доступа к памяти объекта, поэтому вам нужно сериализовать поле по полю.

Поверхность есть, что, поскольку .NET имеет отражение, сериализация объекта таким образом не является трудной. На самом деле, это намного проще, чем сериализация класса C++, который содержит указатели на другие классы C++.

+0

Так что из-за.NET, так много занимаясь управлением памятью, у вас нет прямого доступа к памяти, и даже если бы вы это сделали, это было бы опасно. Это имеет большой смысл, спасибо! :) – user3604097

1

Формат бинарной сериализации .NET отсылает к типам, как они хотели бы быть сохранены и помещены в некоторые метаданные, чтобы вы знали, как их декодировать (какой тип, какое имя поля и т. Д.).

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

В C, если вы меняете структуру каким-либо образом - и вы только что использовали write() для хранения памяти, вы, вероятно, также захотите написать некоторые метаданные, чтобы вы могли знать, была ли у вас правильная версия (и необходимо преобразовать).

Другим преимуществом является то, что языки .NET знают, что делать со ссылками. По умолчанию C будет write() адрес, который будет бесполезен позже. .NET также поддерживает идею полей, которые не следует сериализовать (например, пароль) - еще одна вещь, которую вам нужно будет написать вручную в версии C.

Смежные вопросы