Je veux sérialiser des objets en chaînes et inversement.
Nous utilisons protobuf-net pour transformer un objet en Stream et inversement, avec succès.
Cependant, Stream to string et retour ... pas si réussi. Après avoir traversé StreamToString
et StringToStream
, le nouveau Stream
n'est pas désérialisé par protobuf-net; il soulève une Arithmetic Operation resulted in an Overflow
exception. Si nous désérialisons le flux d'origine, cela fonctionne.
Nos méthodes:
public static string StreamToString(Stream stream)
{
stream.Position = 0;
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
public static Stream StringToStream(string src)
{
byte[] byteArray = Encoding.UTF8.GetBytes(src);
return new MemoryStream(byteArray);
}
Notre exemple de code utilisant ces deux:
MemoryStream stream = new MemoryStream();
Serializer.Serialize<SuperExample>(stream, test);
stream.Position = 0;
string strout = StreamToString(stream);
MemoryStream result = (MemoryStream)StringToStream(strout);
var other = Serializer.Deserialize<SuperExample>(result);
c#
.net
serialization
deserialization
protobuf-net
flipuhdelphia
la source
la source
Réponses:
C'est si courant mais si profondément faux. Les données Protobuf ne sont pas des données de type chaîne. Ce n'est certainement pas ASCII. Vous utilisez l'encodage à l' envers . Un encodage de texte transfère:
Vous n'avez pas d '"octets formatés". Vous avez des octets arbitraires . Vous devez utiliser quelque chose comme un encodage base-n (généralement: base-64). Ce transfert
regardez Convert.ToBase64String et Convertir. FromBase64String
la source
BinaryFormatter
, similaire à cet exemple étrange ?Je viens de tester cela et fonctionne très bien.
Si
stream
a déjà été écrit, vous voudrez peut-être chercher au début avant de commencer avant de lire le texte:stream.Seek(0, SeekOrigin.Begin);
la source
une conversion UTF8 MemoryStream en chaîne:
la source
var array = stream.ToArray(); var str = Encoding.UTF8.GetString(array, 0, array.Length);
. Voir aussi msdn.microsoft.com/en-us/library/…ToArray()
alloue un nouveau tableau en mémoire et copie les données du tampon, ce qui peut avoir de graves implications si vous traitez beaucoup de données.Lorsque vous testez, essayez avec le
UTF8
flux Encode comme ci-dessousla source
Essaye ça.
la source
J'ai écrit une méthode utile pour appeler toute action qui prend un
StreamWriter
et l'écrire dans une chaîne à la place. La méthode est comme ça;Et vous pouvez l'utiliser comme ça;
Je sais que cela peut être fait beaucoup plus facilement avec a
StringBuilder
, le fait est que vous pouvez appeler n'importe quelle méthode qui prend aStreamWriter
.la source
Différent des autres réponses, mais le moyen le plus simple de faire exactement cela pour la plupart des types d'objets est XmlSerializer:
Toutes vos propriétés publiques des types pris en charge seront sérialisées. Même certaines structures de collection sont prises en charge et aboutiront aux propriétés des sous-objets. Vous pouvez contrôler le fonctionnement de la sérialisation avec les attributs de vos propriétés.
Cela ne fonctionne pas avec tous les types d'objets, certains types de données ne sont pas pris en charge pour la sérialisation, mais dans l'ensemble, c'est assez puissant et vous n'avez pas à vous soucier de l'encodage.
la source
Dans le cas d'utilisation où vous souhaitez sérialiser / désérialiser les POCO, la bibliothèque JSON de Newtonsoft est vraiment bonne. Je l'utilise pour conserver les POCO dans SQL Server en tant que chaînes JSON dans un champ nvarchar. La mise en garde est que, comme ce n'est pas une véritable dés / sérialisation, il ne conservera pas les membres privés / protégés et la hiérarchie des classes.
la source