C# 将 Stream 转换为 String 并返回……我们缺少什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17801761/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting Stream to String and back...what are we missing?
提问by flipuhdelphia
I want to serialize objects to strings, and back.
我想将对象序列化为字符串,然后返回。
We use protobuf-net to turn an object into a Stream and back, successfully.
我们使用 protobuf-net 将对象转换为 Stream 并成功返回。
However, Stream to string and back... not so successful. After going through StreamToString
and StringToStream
, the new Stream
isn't
deserialized by protobuf-net; it raises an Arithmetic Operation resulted in an Overflow
exception. If we deserialize the original stream, it works.
但是,流到字符串并返回......不是那么成功。经过StreamToString
and 后StringToStream
,新Stream
的没有被protobuf-net反序列化;它引发了一个Arithmetic Operation resulted in an Overflow
例外。如果我们反序列化原始流,它会起作用。
Our methods:
我们的方法:
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);
}
Our example code using these two:
我们的示例代码使用这两个:
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);
采纳答案by Marc Gravell
This is so common but so profoundly wrong. Protobuf data is not string data. It certainly isn't ASCII. You are using the encoding backwards. A text encoding transfers:
这太普遍了,但却是极其错误的。Protobuf 数据不是字符串数据。它当然不是 ASCII。您正在向后使用编码。一个文本编码传输:
- an arbitrary string to formatted bytes
- formatted bytes to the original string
- 任意字符串到格式化字节
- 格式化字节到原始字符串
You do not have "formatted bytes". You have arbitrary bytes. You need to use something like a base-n (commonly: base-64) encode. This transfers
您没有“格式化字节”。你有任意字节。您需要使用类似 base-n(通常:base-64)编码的东西。这转移
- arbitrary bytes to a formatted string
- a formatted string to the original bytes
- 任意字节到格式化字符串
- 一个格式化的字符串到原始字节
look at Convert.ToBase64String and Convert. FromBase64String
看看 Convert.ToBase64String 和 Convert。来自Base64String
回答by Ehsan
I have just tested this and works fine.
我刚刚测试了这个并且工作正常。
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();
If stream
has already been written to, you might want to seek to the beginning before first before reading out the text: stream.Seek(0, SeekOrigin.Begin);
如果stream
已经写入,您可能需要在阅读文本之前先寻找开头:stream.Seek(0, SeekOrigin.Begin);
回答by Damith
When you testing try with UTF8
Encode stream like below
当您测试时尝试使用UTF8
如下编码流
var stream = new MemoryStream();
var streamWriter = new StreamWriter(stream, System.Text.Encoding.UTF8);
Serializer.Serialize<SuperExample>(streamWriter, test);
回答by user3588327
Try this.
尝试这个。
string output1 = Encoding.ASCII.GetString(byteArray, 0, byteArray.Length)
回答by MD Luffy
In usecase where you want to serialize/deserialize POCOs, Newtonsoft's JSON library is really good. I use it to persist POCOs within SQL Server as JSON strings in an nvarchar field. Caveat is that since its not true de/serialization, it will not preserve private/protected members and class hierarchy.
在您想要序列化/反序列化 POCO 的用例中,Newtonsoft 的 JSON 库非常好。我使用它在 SQL Server 中将 POCO 作为 JSON 字符串保存在 nvarchar 字段中。警告是因为它不是真正的反/序列化,它不会保留私有/受保护的成员和类层次结构。
回答by Wolfgang Grinfeld
a UTF8 MemoryStream to String conversion:
UTF8 MemoryStream 到 String 的转换:
var res = Encoding.UTF8.GetString(stream.GetBuffer(), 0 , (int)stream.Length)
回答by Steztric
I wrote a useful method to call any action that takes a StreamWriter
and write it out to a string instead. The method is like this;
我编写了一个有用的方法来调用任何需要 a 的操作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);
}
}
And you can use it like this;
你可以这样使用它;
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);
I know this can be done much easier with a StringBuilder
, the point is that you can call any method that takes a StreamWriter
.
我知道使用 a 可以更容易地做到这StringBuilder
一点,重点是您可以调用任何需要 a 的方法StreamWriter
。
回答by Denise Skidmore
I want to serialize objects to strings, and back.
我想将对象序列化为字符串,然后返回。
Different from the other answers, but the most straightforward way to do exactly that for most object types is XmlSerializer:
与其他答案不同,但对大多数对象类型执行此操作的最直接方法是 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
}
All your public properties of supported types will be serialized. Even some collection structures are supported, and will tunnel down to sub-object properties. You can control how the serialization works with attributeson your properties.
所有受支持类型的公共属性都将被序列化。甚至支持一些集合结构,并将隧道向下传递到子对象属性。您可以控制序列化如何处理您的属性上的属性。
This does not work with all object types, some data types are not supported for serialization, but overall it is pretty powerful, and you don't have to worry about encoding.
这并不适用于所有对象类型,某些数据类型不支持序列化,但总体而言它非常强大,您不必担心编码。