158 votes

Convertir n'importe quel objet en octet []

Je suis en train d'écrire un prototype de connexion TCP et je vais avoir quelques difficultés à homogénéiser les données à envoyer.

Pour le moment, je suis l'envoi de rien, mais les cordes, mais dans l'avenir, nous voulons être en mesure d'envoyer n'importe quel objet.

Le code est assez simple pour le moment, parce que je pensais que tout ce qui pourrait être jeté dans un tableau d'octets:

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

Bien sûr, cela se trouve assez facilement résolu avec un

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

Le problème est que si je le fais de cette façon, j'ai besoin de vérifier, pour CHAQUE type d'objet qui ne peut pas être lancée à un byte[] au moment de l'exécution.

Depuis que je ne connais pas tous les objets qui ne peuvent pas être jeté dans un byte[] au moment de l'exécution, ce n'est vraiment pas une option.

Comment convertir n'importe quel objet dans un tableau d'octets en C# .NET 4.0?

218voto

Daniel DiPaolo Points 24085

Utilisez les BinaryFormatter :

 private 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();
    }
}
 

112voto

kombsh Points 740

Utilisez le code ci-dessous

     // 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;
    }
 

35voto

Aberro Points 9

Comme d'autres ont dit avant, vous pouvez utiliser la sérialisation binaire, mais elle peut produire une octets supplémentaires ou désérialisés en objet avec pas exactement les mêmes données. L'utilisation de la réflexion sur l'autre main est assez compliqué. Il y a une autre solution qui sera strictement convertir votre objet d'octets et vice-versa - triage:

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(font.LogFont, ptr, false);
// Copy data from unmanaged memory to managed buffer.
Marshal.Copy(ptr, bytes, 0, size);
// Release unmanaged memory.
Marshal.FreeHGlobal(ptr);

Et pour convertir les octets de l'objet:

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);

C'est assez lent et dangereux à utiliser dans la plupart des cas, mais il est facile d'strictement convertit l'objet en byte[] sans la mise en œuvre de la sérialisation et sans attribut [Serializable].

15voto

JaredPar Points 333733

Ce que vous recherchez, c'est la sérialisation. Il existe plusieurs formes de sérialisation disponibles pour la plate-forme .Net

-2voto

Itay Karo Points 10446

Que diriez-vous de la sérialisation? jetez un coup d'oeil ici .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X