.net 将流转换为字符串,然后再转换回来

zqdjd7g9  于 2022-11-19  发布在  .NET
关注(0)|答案(9)|浏览(405)

我想将对象序列化为字符串,然后再返回。
我们使用protobuf-net成功地将一个对象转换成一个Stream并返回。
但是,Stream to string and back...不是很成功,在经过StreamToStringStringToStream之后,新的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);
jv2fixgn

jv2fixgn1#

我刚刚测试了这个,效果很好。

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,则在阅读文本之前,您可能希望查找到first之前的开头:stream.Seek(0, SeekOrigin.Begin);

hmtdttj4

hmtdttj42#

这很常见,但却大错特错。Protobuf数据不是字符串数据,当然也不是ASCII。您使用的是反向编码。文本编码传输:

  • 将任意字符串转换为格式化字节
  • 将格式化字节转换为原始字符串

您没有“格式化字节”。您有 * 任意字节 *。您需要使用诸如base-n(通常为:base-64)编码。这会将

  • 将任意字节转换为格式化字符串
  • 将格式化字符串转换为原始字节

看看Convert.ToBase64StringConvert.FromBase64String

gpnt7bae

gpnt7bae3#

UTF8内存流到字符串的转换:

var res = Encoding.UTF8.GetString(stream.GetBuffer(), 0 , (int)stream.Length)
tct7dpnv

tct7dpnv4#

测试时,尝试使用UTF8编码流,如下所示

var stream = new MemoryStream();
var streamWriter = new StreamWriter(stream, System.Text.Encoding.UTF8);
Serializer.Serialize<SuperExample>(streamWriter, test);
slsn1g29

slsn1g295#

试试这个

string output1 = Encoding.ASCII.GetString(byteArray, 0, byteArray.Length)
eiee3dmh

eiee3dmh6#

StreamReader reader = new StreamReader(strm, System.Text.Encoding.UTF8);
        var final1 = reader.ReadToEnd();

大多数问题的主要原因是编码类型...默认情况下,System.Text.Encoding.UTF8修复了该问题...
好好享受...

2wnc66cl

2wnc66cl7#

我写了一个有用的方法来调用任何执行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的方法。

tkclm6bt

tkclm6bt8#

我想将对象序列化为字符串,然后再返回。
与其他答案不同,但对于大多数对象类型,最直接的方法是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
这并不适用于所有对象类型,有些数据类型不支持序列化,但总的来说,它非常强大,您不必担心编码。

k5hmc34c

k5hmc34c9#

在您想要序列化/反序列化POCO的情况下,Newtonsoft的JSON库非常好。我使用它在SQL Server中将POCO作为nvarchar字段中的JSON字符串持久化。警告是,由于它不是真正的反序列化/反序列化,因此不会保留私有/受保护的成员和类层次结构。

相关问题