Convert any object to byte []

I am writing a prototype TCP connection, and I am having problems homogenizing the data being sent.

At the moment I am sending only strings, but in the future we want to send any object.

At the moment, the code is pretty simple, because I thought everything could be passed to an array of bytes:

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[]'. ... } 

This, of course, is easy enough to solve with

 if( state.headerObject is System.String ){...} 

The problem is that if I do this like that, I need to check the type of EVERY type that cannot be executed for byte [] at runtime.

Since I do not know every object that cannot be executed in byte [] at runtime, this is really not an option.

How to convert any object in general to an array of bytes in C # .NET 4.0?

+85
object c # byte
Feb 01 '11 at 16:23
source share
12 answers

Use BinaryFormatter :

 byte[] ObjectToByteArray(object obj) { if(obj == null) return null; BinaryFormatter bf = new BinaryFormatter(); using (MemoryStream ms = new MemoryStream()) { bf.Serialize(ms, obj); return ms.ToArray(); } } 

Note that obj and any properties / fields inside obj (and so on for all of its properties / fields) must all be Serializable to successfully serialize with this.

+132
Feb 01 '11 at 16:25
source share

checkout this article: http://www.morgantechspace.com/2013/08/convert-object-to-byte-array-and-vice.html

Use the code below

 // Convert an object to a byte array private byte[] ObjectToByteArray(Object obj) { if(obj == null) return null; BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); bf.Serialize(ms, obj); return ms.ToArray(); } // Convert a byte array to an Object private Object ByteArrayToObject(byte[] arrBytes) { MemoryStream memStream = new MemoryStream(); BinaryFormatter binForm = new BinaryFormatter(); memStream.Write(arrBytes, 0, arrBytes.Length); memStream.Seek(0, SeekOrigin.Begin); Object obj = (Object) binForm.Deserialize(memStream); return obj; } 
+70
Aug 13 '13 at 9:15
source share

As before, you can use binary serialization, but it can create extra bytes or deserialize into objects with not exactly the same data. Using thinking on the other hand is quite difficult and very slow. There is another solution that can strictly convert your objects to bytes and vice versa - sort:

 var size = Marshal.SizeOf(your_object); // Both managed and unmanaged buffers required. var bytes = new byte[size]; var ptr = Marshal.AllocHGlobal(size); // Copy object byte-to-byte to unmanaged memory. Marshal.StructureToPtr(your_object, ptr, false); // Copy data from unmanaged memory to managed buffer. Marshal.Copy(ptr, bytes, 0, size); // Release unmanaged memory. Marshal.FreeHGlobal(ptr); 

And to convert bytes to an object:

 var bytes = new byte[size]; var ptr = Marshal.AllocHGlobal(size); Marshal.Copy(bytes, 0, ptr, size); var your_object = (YourType)Marshal.PtrToStructure(ptr, typeof(YourType)); Marshal.FreeHGlobal(ptr); 

It is noticeably slower and partially unsafe to use this approach for small objects and structures compared to your own field serialization field (due to double copying from / to unmanaged memory), but this is the easiest way to strictly convert an object to byte [] without implementing serialization and without the [Serializable] attribute.

+14
Oct 19 '13 at 15:56
source share

What you are looking for is serialization. There are several forms of serialization for the .NET platform.

+11
Feb 01 '11 at 16:25
source share
 public static class SerializerDeserializerExtensions { public static byte[] Serializer(this object _object) { byte[] bytes; using (var _MemoryStream = new MemoryStream()) { IFormatter _BinaryFormatter = new BinaryFormatter(); _BinaryFormatter.Serialize(_MemoryStream, _object); bytes = _MemoryStream.ToArray(); } return bytes; } public static T Deserializer<T>(this byte[] _byteArray) { T ReturnValue; using (var _MemoryStream = new MemoryStream(_byteArray)) { IFormatter _BinaryFormatter = new BinaryFormatter(); ReturnValue = (T)_BinaryFormatter.Deserialize(_MemoryStream); } return ReturnValue; } } 

You can use it as below.

  DataTable _DataTable = new DataTable(); _DataTable.Columns.Add(new DataColumn("Col1")); _DataTable.Columns.Add(new DataColumn("Col2")); _DataTable.Columns.Add(new DataColumn("Col3")); for (int i = 0; i < 10; i++) { DataRow _DataRow = _DataTable.NewRow(); _DataRow["Col1"] = (i + 1) + "Column 1"; _DataRow["Col2"] = (i + 1) + "Column 2"; _DataRow["Col3"] = (i + 1) + "Column 3"; _DataTable.Rows.Add(_DataRow); } byte[] ByteArrayTest = _DataTable.Serializer(); DataTable dt = ByteArrayTest.Deserializer<DataTable>(); 
+5
May 25 '15 at 9:55
source share

You can use the built-in serialization tools within the framework and serialize the MemoryStream . This may be the easiest option, but may lead to an increase in byte [], which may be strictly necessary for your script.

If so, you can use reflection to iterate over the fields and / or properties of the object to be serialized, and manually write them to a MemoryStream, causing serialization to recursively, if necessary, to serialize non-trivial types. This method is more complex and will take longer to implement, but allows you much more control over the serialized stream.

+1
Feb 01 '11 at 16:28
source share

An alternative way to convert an object to an array of bytes:

  TypeConverter objConverter = TypeDescriptor.GetConverter(objMsg.GetType()); byte[] data = (byte[])objConverter.ConvertTo(objMsg, typeof(byte[])); 
+1
Jan 07 '14 at 3:31
source share

How about serialization? look here .

0
Feb 01 '11 at 16:26
source share

I would rather use the expression "serialization" than "casting into bytes". Serializing an object means converting it into an array of bytes (or XML or something else) that you can use in a remote field to re-construct the object. In .NET, the Serializable attribute indicates type labels whose objects can be serialized.

Cheers, Matthias

0
Feb 01 '11 at 16:27
source share

One additional implementation that uses Newtonsoft.Json is binary JSON and does not require labeling everything with the [Serializable] attribute. The only drawback is that the object must be wrapped in an anonymous class, so the byte array obtained using binary serialization may differ from this.

 public static byte[] ConvertToBytes(object obj) { using (var ms = new MemoryStream()) { using (var writer = new BsonWriter(ms)) { var serializer = new JsonSerializer(); serializer.Serialize(writer, new { Value = obj }); return ms.ToArray(); } } } 

An anonymous class is used because BSON must start with a class or array. I did not try to deserialize byte [] back to the object and not sure if it works, but I checked the conversion speed to byte [], and it fully satisfies my needs.

0
Feb 23 '17 at 12:42 on
source share

Combined solutions in the Extensions class:

 public static class Extensions { public static byte[] ToByteArray(this object obj) { var size = Marshal.SizeOf(data); var bytes = new byte[size]; var ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(data, ptr, false); Marshal.Copy(ptr, bytes, 0, size); Marshal.FreeHGlobal(ptr); return bytes; } public static string Serialize(this object obj) { return JsonConvert.SerializeObject(obj); } } 
0
Jul 30 '17 at 16:26
source share

How about something simple?

 return ((object[])value).Cast<byte>().ToArray(); 
0
Nov 14 '17 at 12:49 on
source share



All Articles