你如何从一个MemoryStream获得一个string?
如果给我一个MemoryStream
,我知道已经填充了一个String
,我怎么得到一个String
退出?
此示例显示如何读取和写入一个string到MemoryStream。
static void Main(string[] args) { using (var ms = new MemoryStream()) { var sw = new StreamWriter(ms); sw.WriteLine("Hello World"); // The string is currently stored in the // StreamWriters buffer. Flushing the stream will // force the string into the MemoryStream. sw.Flush(); // If we dispose the StreamWriter now, it will close // the BaseStream (which is our MemoryStream) which // will prevent us from reading from our MemoryStream //DON'T DO THIS - sw.Dispose(); // The StreamReader will read from the current // position of the MemoryStream which is currently // set at the end of the string we just wrote to it. // We need to set the position to 0 in order to read // from the beginning. ms.Position = 0; var sr = new StreamReader(ms); var myStr = sr.ReadToEnd(); Console.WriteLine(myStr); } Console.WriteLine("Press any key to continue."); Console.ReadKey(); }
你也可以使用
Encoding.ASCII.GetString(ms.ToArray());
我不认为这是有效的,但我不能发誓。 它也可以让你select不同的编码,而使用StreamReader你必须指定它作为参数。
使用StreamReader将MemoryStream转换为string。
<Extension()> _ Public Function ReadAll(ByVal memStream As MemoryStream) As String ' Reset the stream otherwise you will just get an empty string. ' Remember the position so we can restore it later. Dim pos = memStream.Position memStream.Position = 0 Dim reader As New StreamReader(memStream) Dim str = reader.ReadToEnd() ' Reset the position so that subsequent writes are correct. memStream.Position = pos Return str End Function
使用StreamReader ,然后可以使用返回string的ReadToEnd方法。
以前的解决scheme不适用于涉及编码的情况。 这里是 – 一种“现实生活” – 例如如何正确地做到这一点…
using(var stream = new System.IO.MemoryStream()) { var serializer = new DataContractJsonSerializer(typeof(IEnumerable<ExportData>), new[]{typeof(ExportData)}, Int32.MaxValue, true, null, false); serializer.WriteObject(stream, model); var jsonString = Encoding.Default.GetString((stream.ToArray())); }
这个示例演示了如何从MemoryStream中读取一个string,其中我使用了序列化(使用DataContractJsonSerializer),将string从某个服务器传递到客户端,然后如何从作为parameter passing的string中恢复MemoryStream,然后,反序列化MemoryStream。
我已经使用不同职位的部分来执行此示例。
希望这有助于。
using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Threading; namespace JsonSample { class Program { static void Main(string[] args) { var phones = new List<Phone> { new Phone { Type = PhoneTypes.Home, Number = "28736127" }, new Phone { Type = PhoneTypes.Movil, Number = "842736487" } }; var p = new Person { Id = 1, Name = "Person 1", BirthDate = DateTime.Now, Phones = phones }; Console.WriteLine("New object 'Person' in the server side:"); Console.WriteLine(string.Format("Id: {0}, Name: {1}, Birthday: {2}.", p.Id, p.Name, p.BirthDate.ToShortDateString())); Console.WriteLine(string.Format("Phone: {0} {1}", p.Phones[0].Type.ToString(), p.Phones[0].Number)); Console.WriteLine(string.Format("Phone: {0} {1}", p.Phones[1].Type.ToString(), p.Phones[1].Number)); Console.Write(Environment.NewLine); Thread.Sleep(2000); var stream1 = new MemoryStream(); var ser = new DataContractJsonSerializer(typeof(Person)); ser.WriteObject(stream1, p); stream1.Position = 0; StreamReader sr = new StreamReader(stream1); Console.Write("JSON form of Person object: "); Console.WriteLine(sr.ReadToEnd()); Console.Write(Environment.NewLine); Thread.Sleep(2000); var f = GetStringFromMemoryStream(stream1); Console.Write(Environment.NewLine); Thread.Sleep(2000); Console.WriteLine("Passing string parameter from server to client..."); Console.Write(Environment.NewLine); Thread.Sleep(2000); var g = GetMemoryStreamFromString(f); g.Position = 0; var ser2 = new DataContractJsonSerializer(typeof(Person)); var p2 = (Person)ser2.ReadObject(g); Console.Write(Environment.NewLine); Thread.Sleep(2000); Console.WriteLine("New object 'Person' arrived to the client:"); Console.WriteLine(string.Format("Id: {0}, Name: {1}, Birthday: {2}.", p2.Id, p2.Name, p2.BirthDate.ToShortDateString())); Console.WriteLine(string.Format("Phone: {0} {1}", p2.Phones[0].Type.ToString(), p2.Phones[0].Number)); Console.WriteLine(string.Format("Phone: {0} {1}", p2.Phones[1].Type.ToString(), p2.Phones[1].Number)); Console.Read(); } private static MemoryStream GetMemoryStreamFromString(string s) { var stream = new MemoryStream(); var sw = new StreamWriter(stream); sw.Write(s); sw.Flush(); stream.Position = 0; return stream; } private static string GetStringFromMemoryStream(MemoryStream ms) { ms.Position = 0; using (StreamReader sr = new StreamReader(ms)) { return sr.ReadToEnd(); } } } [DataContract] internal class Person { [DataMember] public int Id { get; set; } [DataMember] public string Name { get; set; } [DataMember] public DateTime BirthDate { get; set; } [DataMember] public List<Phone> Phones { get; set; } } [DataContract] internal class Phone { [DataMember] public PhoneTypes Type { get; set; } [DataMember] public string Number { get; set; } } internal enum PhoneTypes { Home = 1, Movil = 2 } }
在这种情况下,如果你真的想用一个简单的方法在MemoryStream
使用ReadToEnd
方法,你可以使用这个扩展方法来实现这个:
public static class SetExtensions { public static string ReadToEnd(this MemoryStream BASE) { BASE.Position = 0; StreamReader R = new StreamReader(BASE); return R.ReadToEnd(); } }
你可以这样使用这个方法:
using (MemoryStream m = new MemoryStream()) { //for example i want to serialize an object into MemoryStream //I want to use XmlSeralizer XmlSerializer xs = new XmlSerializer(_yourVariable.GetType()); xs.Serialize(m, _yourVariable); //the easy way to use ReadToEnd method in MemoryStream MessageBox.Show(m.ReadToEnd()); }
Brian的答案稍微修改版本允许可选的pipe理读取开始,这似乎是最简单的方法。 可能不是最高效的,但容易理解和使用。
Public Function ReadAll(ByVal memStream As MemoryStream, Optional ByVal startPos As Integer = 0) As String ' reset the stream or we'll get an empty string returned ' remember the position so we can restore it later Dim Pos = memStream.Position memStream.Position = startPos Dim reader As New StreamReader(memStream) Dim str = reader.ReadToEnd() ' reset the position so that subsequent writes are correct memStream.Position = Pos Return str End Function
为什么不在MemoryStreamtypes上做一个漂亮的扩展方法?
public static class MemoryStreamExtensions { static object streamLock = new object(); public static void WriteLine(this MemoryStream stream, string text, bool flush) { byte[] bytes = Encoding.UTF8.GetBytes(text + Environment.NewLine); lock (streamLock) { stream.Write(bytes, 0, bytes.Length); if (flush) { stream.Flush(); } } } public static void WriteLine(this MemoryStream stream, string formatString, bool flush, params string[] strings) { byte[] bytes = Encoding.UTF8.GetBytes(String.Format(formatString, strings) + Environment.NewLine); lock (streamLock) { stream.Write(bytes, 0, bytes.Length); if (flush) { stream.Flush(); } } } public static void WriteToConsole(this MemoryStream stream) { lock (streamLock) { long temporary = stream.Position; stream.Position = 0; using (StreamReader reader = new StreamReader(stream, Encoding.UTF8, false, 0x1000, true)) { string text = reader.ReadToEnd(); if (!String.IsNullOrEmpty(text)) { Console.WriteLine(text); } } stream.Position = temporary; } } }
当然,将这些方法与标准方法结合使用时要小心。 🙂 …你需要使用那个方便的streamLock,如果你这样做,为了并发。
byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2"); MemoryStream streamItem = new MemoryStream(array); // convert to string StreamReader reader = new StreamReader(streamItem); string text = reader.ReadToEnd();