132 votes

Comment convertir un objet en tableau d'octets en C# ?

J'ai une collection d'objets que je dois écrire dans un fichier binaire.

J'ai besoin que les octets du fichier soient compacts, donc je ne peux pas utiliser BinaryFormatter . BinaryFormatter ajoute toutes sortes d'informations pour les besoins de la désérialisation.

Si j'essaie

byte[] myBytes = (byte[]) myObject 

J'obtiens une exception d'exécution.

J'ai besoin que ce soit rapide, donc je préfère ne pas avoir à copier des tableaux d'octets. Je voudrais juste que le cast byte[] myBytes = (byte[]) myObject au travail !

OK, juste pour être clair, je ne peux pas avoir cualquier dans le fichier de sortie. Seulement les octets de l'objet. Emballé d'objet à objet. D'après les réponses reçues, il semble que j'écrirai des Buffer.BlockCopy code. Peut-être en utilisant un code peu sûr.

14voto

Marc Gravell Points 482669

Il s'agit en fait de la sérialisation, qui peut prendre de nombreuses formes. Puisque vous voulez du petit et du binaire, les tampons de protocole peuvent être une option viable - offrant également la tolérance de version et la portabilité. Contrairement à BinaryFormatter Le format des fils des tampons de protocole n'inclut pas toutes les métadonnées de type, mais seulement des marqueurs très laconiques pour identifier les données.

En .NET, il existe quelques implémentations ; en particulier

Je dirais humblement que protobuf-net (que j'ai écrit) permet une utilisation plus idiomatique de .NET avec des classes typiques de C# (les protocol-buffers "normaux" ont tendance à demande génération de codes) ; par exemple :

[ProtoContract]
public class Person {
   [ProtoMember(1)]
   public int Id {get;set;}
   [ProtoMember(2)]
   public string Name {get;set;}
}
....
Person person = new Person { Id = 123, Name = "abc" };
Serializer.Serialize(destStream, person);
...
Person anotherPerson = Serializer.Deserialize<Person>(sourceStream);

4voto

The Berga Points 2278

Cela a fonctionné pour moi :

byte[] bfoo = (byte[])foo;

foo est un objet dont je suis sûr à 100 % qu'il s'agit d'un tableau d'octets.

3voto

Ali Soltani Points 1

J'ai trouvé la meilleure méthode, cette méthode a fonctionné correctement pour moi. Utiliser Newtonsoft.Json

public TData ByteToObj<TData>(byte[] arr){
                    return JsonConvert.DeserializeObject<TData>(Encoding.UTF8.GetString(arr));
    }

public byte[] ObjToByte<TData>(TData data){
            var json = JsonConvert.SerializeObject(data);
            return Encoding.UTF8.GetBytes(json);
}

2voto

Atmocreations Points 3300

Jetez un coup d'œil à Sérialisation La technique de "conversion" d'un objet entier en un flux d'octets. Vous pouvez l'envoyer sur le réseau ou l'écrire dans un fichier, puis le restaurer ultérieurement sous forme d'objet.

1voto

Jason Williams Points 31901

Pour accéder directement à la mémoire d'un objet (pour faire un "core dump"), vous devez passer par du code non sécurisé.

Si vous voulez quelque chose de plus compact que BinaryWriter ou un vidage de mémoire brut, vous devez écrire un code de sérialisation personnalisé qui extrait les informations critiques de l'objet et les emballe de manière optimale.

editar P.S. Il est très facile d'intégrer l'approche BinaryWriter dans un DeflateStream pour compresser les données, ce qui permet généralement de réduire de moitié la taille des données.

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