26

okay guys I'm seeing question from persons asking how to convert byte arrays to int, string, Stream, etc... and the answers to which are all varying and I have personally not found any satisfactory answers.

So here are some types that we want to convert an array of bytes to.

UnityEngine.Font which can take in ttf data.

UnityEngine.Testure2D which h can take in data from image files like .png, .jpg, etc...

How would we convert a byte array to a String, UnityEngine.Testure2D,UnityEngine.Font, Bitmap, etc...

The data that populates the byte array must be from a file type whose data can by managed by the type we want to convert the byte array to?

Is this currently possible?

Any help would be appreciated.

Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
  • 1
    A byte array is just that. It's a series of bytes. There's no way to know if those bytes belong to a string, an int, a `UnityEngine.Font`, etc. They are just bytes. You would have to "deserialize" the bytes by passing in a `Type` parameter, so it would know what type of object it is. – Icemanind Oct 08 '15 at 17:51
  • ooooooh great. can you give a quick example ? –  Oct 08 '15 at 17:55
  • 2
    Never convert a byte array to a string unless it is a string. Can really screw up the code. Chrs/Strings are two byte objects in Net and you have to be careful to use correct encoding. Sending/Receiving data is usually done by sending a byte array. Any object must be serialized (meaning converting to bytes) and then de-serialize. Binary data like .png and jpg are singular byte arrays objects and can be simply converted to a byte array. Complex object need better definitions of fields sizes before serialized so they can be properly de-serialized. That is why you see varying answers. – jdweng Oct 08 '15 at 19:01
  • Thanks a lot for the info and advice –  Oct 08 '15 at 20:38

4 Answers4

53

Primitive types are easy because they have a defined representation as a byte array. Other objects are not because they may contain things that cannot be persisted, like file handles, references to other objects, etc.

You can try persisting an object to a byte array using BinaryFormatter:

public byte[] ToByteArray<T>(T obj)
{
    if(obj == null)
        return null;
    BinaryFormatter bf = new BinaryFormatter();
    using(MemoryStream ms = new MemoryStream())
    {
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
}

public T FromByteArray<T>(byte[] data)
{
    if(data == null)
         return default(T);
    BinaryFormatter bf = new BinaryFormatter();
    using(MemoryStream ms = new MemoryStream(data))
    {
        object obj = bf.Deserialize(ms);
        return (T)obj;
    }
}

But not all types are serializable. There's no way to "store" a connection to a database, for example. You can store the information that's used to create the connection (like the connection string) but you can't store the actual connection object.


UPDATE

BinaryFormatter is now considered "insecure", especially when trying to deserialize data from untrusted sources. Which makes sense, since you're essentially loading raw binary data into memory that could do bad things.

Suggested alternatives are to use a non-binary format like XML or JSON for generic object graphs, or write custom binary serialization code to serialize primitive members explicitly.

D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • I really like your answer , I am testing it out here . I am getting an error . Here is my code and . i point out what and where the error is . :) –  Oct 08 '15 at 20:34
  • the error in my code is here `Byte[] ba = ToByteArray(myStream); //SerializationException: Type System.IO.UnmanagedMemoryStream is not marked as Serializable.` –  Oct 08 '15 at 20:35
  • 2
    If it's not serializable, then you can't, well, serialize it. What do you expect to do with a serailized _stream_ anyways. It's just a mechanism to move data; it diesn't have any data in and of itself. – D Stanley Oct 08 '15 at 20:50
  • 4
    Now `BinaryFormatter` is obsolete and insecure, please read: [CA2300: Do not use insecure deserializer BinaryFormatter](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2300) & [BinaryFormatter security guide](https://learn.microsoft.com/en-us/dotnet/standard/serialization/binaryformatter-security-guide). – Igor Aug 31 '21 at 04:52
4

you can deserialize the byte array to a class object like this in .Net 6.

using System.Text.Json;

using MemoryStream ms = new MemoryStream(bytes);
Examlple ex = JsonSerializer.Deserialize<Example>(ms);
Console.WriteLine(ex.Value);

class Example
{
    string Value {get; set; }
}
Vivek Nuna
  • 25,472
  • 25
  • 109
  • 197
2

In C# it is easy you can follow the below approach to convert a byte array into any object

byte[] bytesFromBase64 = Convert.FromBase64String(message.Body.ToString());
string stringData = Encoding.UTF8.GetString(bytesFromBase64);
Order order = JsonConvert.DeserializeObject<Order>(stringData);
Sameel
  • 133
  • 1
  • 5
-9

c++ template version :

template<typename T>
void fromByteArray(T& t, byte *bytes)
{
  t = *(T*)bytes;
};

template<typename T>
byte * toByteArray(T& t) 
{
  return (byte*)&t;
};
sailfish009
  • 2,561
  • 1
  • 24
  • 31