我想将对象序列化为字符串,然后返回。
我们使用protobuf-net将对象转换为Stream并成功返回。
但是,Stream to string and back ...不太成功。经过StreamToString
和StringToStream
之后,新的Stream
没有被protobuf-net反序列化;它提出了一个Arithmetic Operation resulted in an Overflow
例外。如果我们反序列化原始流,它可以工作。
我们的方法:
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);
}
我们的示例代码使用这两个:
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);
这是如此常见但却非常错误。 Protobuf数据不是字符串数据。它当然不是ASCII。您正在向后使用编码。文本编码传输:
您没有“格式化字节”。你有任意字节。你需要使用类似base-n(通常是:base-64)编码的东西。这转移
看看Convert.ToBase64String和Convert。 FromBase64String
我刚测试过这个并且运行正常。
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();
如果已经写过stream
,你可能想在读出文本之前先寻找开头:stream.Seek(0, SeekOrigin.Begin);
当您尝试使用UTF8
编码流时,如下所示
var stream = new MemoryStream();
var streamWriter = new StreamWriter(stream, System.Text.Encoding.UTF8);
Serializer.Serialize<SuperExample>(streamWriter, test);
试试这个。
string output1 = Encoding.ASCII.GetString(byteArray, 0, byteArray.Length)
UTF8 MemoryStream到String转换:
var res = Encoding.UTF8.GetString(stream.GetBuffer(), 0 , (int)stream.Length)
我写了一个有用的方法来调用任何需要StreamWriter
并将其写入字符串的操作。方法是这样的;
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);
}
}
你可以像这样使用它;
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);
我知道使用StringBuilder
可以更容易地做到这一点,关键是你可以调用任何需要StreamWriter
的方法。
在您想要序列化/反序列化POCO的用例中,Newtonsoft的JSON库非常好。我用它来将SQL Server中的POCO持久化为nvarchar字段中的JSON字符串。警告是因为它不是真正的de / serialization,它不会保留私有/受保护的成员和类层次结构。
我想将对象序列化为字符串,然后返回。
与其他答案不同,但对大多数对象类型来说,最直接的方法是XmlSerializer:
Subject subject = new Subject();
XmlSerializer serializer = new XmlSerializer(typeof(Subject));
using (Stream stream = new MemoryStream())
{
serializer.Serialize(stream, subject);
// do something with stream
Subject subject2 = (Subject)serializer.Deserialize(stream);
// do something with subject2
}
支持类型的所有公共属性都将被序列化。甚至支持一些集合结构,并将隧道传递到子对象属性。您可以控制序列化在属性上使用attributes的方式。
这不适用于所有对象类型,序列化不支持某些数据类型,但总体来说它非常强大,您不必担心编码。