Eu quero serializar objetos em strings e voltar.
Usamos o protobuf-net para transformar um objeto em um fluxo e retornar com êxito.
No entanto, transmitir para string e voltar ... não é tão bem-sucedido. Depois de passar por StreamToString
e StringToStream
, o novo Stream
não é desserializado pelo protobuf-net; isso gera uma Arithmetic Operation resulted in an Overflow
exceção. Se desserializarmos o fluxo original, ele funcionará.
Nossos métodos:
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);
}
Nosso exemplo de código usando estes dois:
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
fonte
fonte
Respostas:
Isso é tão comum, mas profundamente errado. Dados do Protobuf não são dados de sequência. Certamente não é ASCII. Você está usando a codificação para trás . Uma codificação de texto é transferida:
Você não possui "bytes formatados". Você tem bytes arbitrários . Você precisa usar algo como uma codificação base-n (geralmente: base-64). Isso transfere
veja Convert.ToBase64String e Convert. FromBase64String
fonte
BinaryFormatter
, semelhante a este exemplo estranho ?Acabei de testar isso e funciona bem.
Se
stream
já foi gravado, você pode procurar o começo antes da leitura antes de ler o texto:stream.Seek(0, SeekOrigin.Begin);
fonte
uma conversão UTF8 MemoryStream para String:
fonte
var array = stream.ToArray(); var str = Encoding.UTF8.GetString(array, 0, array.Length);
. Consulte também msdn.microsoft.com/en-us/library/…ToArray()
aloca uma nova matriz na memória e copia os dados do buffer, o que pode ter sérias implicações se você estiver lidando com muitos dados.Ao testar, tente com o
UTF8
codificar stream como abaixofonte
Tente isso.
fonte
Eu escrevi um método útil para chamar qualquer ação que receba um
StreamWriter
e escrevê-lo em uma string. O método é assim;E você pode usá-lo assim;
Eu sei que isso pode ser feito muito mais fácil com a
StringBuilder
, o ponto é que você pode chamar qualquer método que use aStreamWriter
.fonte
Diferente das outras respostas, mas a maneira mais direta de fazer exatamente isso para a maioria dos tipos de objetos é o XmlSerializer:
Todas as suas propriedades públicas dos tipos suportados serão serializadas. Até algumas estruturas de coleção são suportadas e serão direcionadas para as propriedades do subobjeto. Você pode controlar como a serialização funciona com atributos em suas propriedades.
Isso não funciona com todos os tipos de objetos, alguns tipos de dados não são suportados para serialização, mas no geral é bastante poderoso e você não precisa se preocupar com a codificação.
fonte
No caso em que você deseja serializar / desserializar os POCOs, a biblioteca JSON da Newtonsoft é realmente boa. Eu o uso para persistir POCOs no SQL Server como seqüências JSON em um campo nvarchar. Advertência é que, uma vez que não é verdadeira de / serialização, ele não preservará membros privados / protegidos e hierarquia de classes.
fonte