c# - ejemplo - Convirtiendo Stream a String y viceversa... ¿qué nos falta?
string to stream c# (7)
Quiero serializar objetos a cadenas y viceversa.
Usamos protobuf-net para convertir un objeto en una secuencia y volver, con éxito.
Sin embargo, Stream a string y viceversa ... no tan exitoso. Después de pasar por StreamToString
y StringToStream
, el nuevo Stream
no es deserializado por protobuf-net; plantea una Arithmetic Operation resulted in an Overflow
excepción de Arithmetic Operation resulted in an Overflow
. Si deserializamos la transmisión original, funciona.
Nuestros 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);
}
Nuestro código de ejemplo usando estos dos:
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);
Acabo de probar esto y funciona bien.
string test = "Testing 1-2-3";
// convert string to stream
byte[] byteArray = Encoding.ASCII.GetBytes(test);
MemoryStream stream = new MemoryStream(byteArray);
// convert stream to string
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
Si ya se ha escrito la stream
, es posible que desee buscar al principio antes que antes antes de leer el texto: stream.Seek(0, SeekOrigin.Begin);
Cuando pruebas, prueba con UTF8
Encode stream como a continuación
var stream = new MemoryStream();
var streamWriter = new StreamWriter(stream, System.Text.Encoding.UTF8);
Serializer.Serialize<SuperExample>(streamWriter, test);
En el caso de uso en el que desea serializar / deserializar POCO, la biblioteca JSON de Newtonsoft es realmente buena. Lo uso para persistir POCO dentro de SQL Server como cadenas JSON en un campo nvarchar. La advertencia es que, dado que no es verdadera de / serialización, no preservará los miembros privados / protegidos y la jerarquía de clases.
Escribí un método útil para llamar a cualquier acción que tome un StreamWriter
y escribirlo en una cadena. El método es así;
static void SendStreamToString(Action<StreamWriter> action, out string destination)
{
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream, Encoding.Unicode))
{
action(writer);
writer.Flush();
stream.Position = 0;
destination = Encoding.Unicode.GetString(stream.GetBuffer(), 0, (int)stream.Length);
}
}
Y puedes usarlo así;
string myString;
SendStreamToString(writer =>
{
var ints = new List<int> {1, 2, 3};
writer.WriteLine("My ints");
foreach (var integer in ints)
{
writer.WriteLine(integer);
}
}, out myString);
Sé que esto se puede hacer mucho más fácilmente con un StringBuilder
, el punto es que puedes llamar a cualquier método que tome un StreamWriter
.
Esto es tan común pero tan profundamente incorrecto. Los datos de Protobuf no son datos de cadena. Ciertamente no es ASCII. Estás usando la codificación al revés . Una codificación de texto transfiere:
- una cadena arbitraria para bytes formateados
- bytes formateados a la cadena original
Usted no tiene "bytes formateados". Tienes bytes arbitrarios . Necesita usar algo como una codificación de base-n (comúnmente: base-64). Esto transfiere
- bytes arbitrarios a una cadena formateada
- una cadena formateada a los bytes originales
mira Convert.ToBase64String y Convert. FromBase64String
Prueba esto.
string output1 = Encoding.ASCII.GetString(byteArray, 0, byteArray.Length)
una conversión de UTF8 MemoryStream a String:
var res = Encoding.UTF8.GetString(stream.GetBuffer(),0 , stream.GetBuffer().Length)