如果我得到一个MemoryStream
我知道已经填充了一个String
,我怎么得到String
退出?
此示例显示如何读取和写入MemoryStream的字符串.
Imports System.IO Module Module1 Sub Main() ' We don't need to dispose any of the MemoryStream ' because it is a managed object. However, just for ' good practice, we'll close the MemoryStream. Using ms As New MemoryStream Dim sw As 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 '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 Dim sr As New StreamReader(ms) Dim myStr = sr.ReadToEnd() Console.WriteLine(myStr) ' We can dispose our StreamWriter and StreamReader ' now, though this isn't necessary (they don't hold ' any resources open on their own). sw.Dispose() sr.Dispose() End Using Console.WriteLine("Press any key to continue.") Console.ReadKey() End Sub End Module
你也可以使用
Encoding.ASCII.GetString(ms.ToArray());
我认为效率不高,但我不能发誓.它还允许您选择不同的编码,而使用StreamReader则必须将其指定为参数.
使用StreamReader将MemoryStream转换为String.
_ 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,然后您可以使用返回字符串的ReadToEnd方法.
byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2"); MemoryStream streamItem = new MemoryStream(array); // convert to string StreamReader reader = new StreamReader(streamItem); string text = reader.ReadToEnd();
以前的解决方案在涉及编码的情况下不起作用.这是 - 一种"现实生活" - 例如如何正确地做到这一点......
using(var stream = new System.IO.MemoryStream())
{
var serializer = new DataContractJsonSerializer(typeof(IEnumerable), new[]{typeof(ExportData)}, Int32.MaxValue, true, null, false);
serializer.WriteObject(stream, model);
var jsonString = Encoding.Default.GetString((stream.ToArray()));
}
在这种情况下,如果您真的想以简单的方式使用ReadToEnd
方法MemoryStream
,可以使用此扩展方法来实现此目的:
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()); }
此示例演示如何从MemoryStream中读取字符串,其中我使用了序列化(使用DataContractJsonSerializer),将字符串从某个服务器传递到客户端,然后,如何从作为参数传递的字符串中恢复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{ 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 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 } }
Brian的答案稍加修改,允许可选的读取启动管理,这似乎是最简单的方法.可能不是最有效,但易于理解和使用.
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
为什么不在MemoryStream类型上创建一个很好的扩展方法?
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来实现并发性.