Если мне задан MemoryStream
, который, как я знаю, был заполнен с помощью String
, как мне получить String
обратно?
Как вы получаете строку из MemoryStream?
Ответ 1
В этом примере показано, как читать и записывать строку в 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();
}
Ответ 2
Вы также можете использовать
Encoding.ASCII.GetString(ms.ToArray());
Я не думаю, что это менее эффективно, но я не мог поклясться. Он также позволяет вам выбрать другую кодировку, тогда как с помощью StreamReader вы должны указать это как параметр.
Ответ 3
Использование 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
Ответ 4
используйте StreamReader, затем вы можете использовать ReadToEnd, который возвращает строку.
Ответ 5
Предыдущие решения не будут работать в случаях, когда используется кодирование. Вот - вид "реальной жизни" - пример того, как это сделать правильно...
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()));
}
Ответ 6
В этом примере показано, как читать строку из 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
}
}
Ответ 7
В этом случае, если вы действительно хотите использовать метод 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());
}
Ответ 8
byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2");
MemoryStream streamItem = new MemoryStream(array);
// convert to string
StreamReader reader = new StreamReader(streamItem);
string text = reader.ReadToEnd();
Ответ 9
Немного измененная версия ответа Брайана позволяет факультативно управлять началом чтения. Это, пожалуй, самый простой способ. вероятно, не самый эффективный, но понятный и понятный.
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
Ответ 10
Почему бы не сделать хороший метод расширения для типа 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, если вы это сделаете, для concurrency.