Я пишу прототип TCP-соединения, и у меня возникают проблемы с усреднением данных для отправки.
На данный момент я посылаю только строки, но в будущем мы хотим иметь возможность отправлять любые объекты.
На данный момент код довольно прост, потому что я думал, что все можно записать в байтовый массив:
void SendData(object headerObject, object bodyObject)
{
byte[] header = (byte[])headerObject; //strings at runtime,
byte[] body = (byte[])bodyObject; //invalid cast exception
// Unable to cast object of type 'System.String' to type 'System.Byte[]'.
...
}
Это, конечно, достаточно легко решить с помощью
if( state.headerObject is System.String ){...}
Проблема в том, что если я делаю это таким образом, мне нужно проверять КАЖДЫЙ тип объекта, который не может быть приведен к байту [] во время выполнения.
Поскольку я не знаю каждый объект, который нельзя преобразовать в byte [] во время выполнения, это действительно не вариант.
Как вообще преобразовать любой объект в массив байтов в C # .NET 4.0?
FileStream
или любой объект, который инкапсулирует дескриптор подобного типа).Ответы:
Используйте
BinaryFormatter
:Обратите внимание, что
obj
и любые свойства / поля внутриobj
(и так далее для всех их свойств / полей) должны быть помеченыSerializable
атрибутом для успешной сериализации с этим.источник
using
блоке, так как он освободит внутренний используемый буфер.Оформить заказ этой статьи: http://www.morgantechspace.com/2013/08/convert-object-to-byte-array-and-vice.html
Используйте код ниже
источник
MemorySteam
должны быть заключены вusing
блок.Как уже говорили другие, вы можете использовать двоичную сериализацию, но она может создать дополнительные байты или быть десериализована в объекты с не совсем такими же данными. Использование отражения с другой стороны довольно сложно и очень медленно. Есть еще одно решение, которое может строго преобразовывать ваши объекты в байты и наоборот - сортировка:
И преобразовать байты в объект:
Заметно медленнее и отчасти небезопасно использовать этот подход для небольших объектов и структур по сравнению с вашим собственным полем сериализации по полю (из-за двойного копирования из / в неуправляемую память), но это самый простой способ строго преобразовать объект в byte [] без реализации сериализации и без атрибута [Сериализуемый].
источник
StructureToPtr
+Copy
медленно? Как это может быть медленнее, чем сериализация? Есть ли более быстрое решение?var bytes = new byte[size];
То, что вы ищете, это сериализация. Для платформы .Net доступно несколько форм сериализации.
byte[]
источник
Вы можете использовать его, как показано ниже.
источник
Использование
Encoding.UTF8.GetBytes
быстрее, чем использованиеMemoryStream
. Здесь я использую NewtonsoftJson для преобразования входного объекта в строку JSON, а затем получаю байты из строки JSON.Бенчмарк для версии @Daniel DiPaolo с этой версией
источник
Комбинированные решения в классе расширений:
источник
Вы можете использовать встроенные средства сериализации в платформе и сериализовать в MemoryStream . Это может быть самый простой вариант, но он может дать больший byte [], чем может быть строго необходим для вашего сценария.
Если это так, вы можете использовать отражение для перебора полей и / или свойств в объекте, который нужно сериализовать, и вручную записать их в MemoryStream, рекурсивно вызывая сериализацию, если это необходимо для сериализации нетривиальных типов. Этот метод более сложен и требует больше времени для реализации, но дает вам гораздо больше контроля над сериализованным потоком.
источник
Как насчет чего-нибудь такого простого?
источник
Я бы предпочел использовать выражение «сериализация», чем «приведение в байты». Сериализация объекта означает преобразование его в массив байтов (или XML, или что-то еще), который можно использовать в удаленном блоке для воссоздания объекта. В .NET
Serializable
атрибут отмечает типы, чьи объекты можно сериализовать.источник
Альтернативный способ преобразования объекта в байтовый массив:
источник
Еще одна реализация, использующая двоичный файл JSON Newtonsoft.Json и не требующая маркировки всего атрибута [Serializable]. Единственным недостатком является то, что объект должен быть заключен в анонимный класс, поэтому массив байтов, полученный с помощью двоичной сериализации, может отличаться от этого.
Анонимный класс используется потому, что BSON должен начинаться с класса или массива. Я не пробовал десериализовать byte [] обратно в объект и не уверен, работает ли он, но протестировал скорость преобразования в byte [], и это полностью удовлетворяет мои потребности.
источник
Как насчет сериализации? посмотрите здесь .
источник