Как вы получаете строку из потока памяти?
Если мне дадут MemoryStream
что я знаю, был заполнен с String
, как мне получить String
обратно?
10 ответов:
в этом примере показано, как читать и записывать строку в поток памяти.
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 в строку.
<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, вы можете использовать ReadToEnd метод, который возвращает строку.
предыдущие решения не будут работать в тех случаях, когда используется кодирование. Вот-своего рода" реальная жизнь " - пример того, как это правильно сделать...
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())); }
в этом случае, если вы действительно хотите использовать
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<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 } }
byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2"); MemoryStream streamItem = new MemoryStream(array); // convert to string StreamReader reader = new StreamReader(streamItem); string text = reader.ReadToEnd();
немного измененная версия ответа Брайана позволяет дополнительно управлять запуском чтения, это, кажется, самый простой метод. наверное, не самый эффективный, но простой в понимании и использовании.
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, если вы это сделаете, для параллелизма.