How do you get a string from a MemoryStream?

.Netvb.netStringMemorystream

.Net Problem Overview


If I am given a MemoryStream that I know has been populated with a String, how do I get a String back out?

.Net Solutions


Solution 1 - .Net

This sample shows how to read and write a string to a 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

Solution 2 - .Net

You can also use

Encoding.ASCII.GetString(ms.ToArray());

I don't think this is less efficient, but I couldn't swear to it. It also lets you choose a different encoding, whereas using a StreamReader you'd have to specify that as a parameter.

Solution 3 - .Net

Using a StreamReader to convert the MemoryStream to a 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

Solution 4 - .Net

use a StreamReader, then you can use the ReadToEnd method that returns a string.

Solution 5 - .Net

byte[] array = Encoding.ASCII.GetBytes("MyTest1 - MyTest2");
MemoryStream streamItem = new MemoryStream(array);

// convert to string
StreamReader reader = new StreamReader(streamItem);
string text = reader.ReadToEnd();

Solution 6 - .Net

Previous solutions wouldn't work in cases where encoding is involved. Here is - kind of a "real life" - example how to do this properly...

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()));
}

Solution 7 - .Net

In this case, if you really want to use ReadToEnd method in MemoryStream in an easy way, you can use this Extension Method to achieve this:

public static class SetExtensions
{
	public static string ReadToEnd(this MemoryStream BASE)
	{
		BASE.Position = 0;
		StreamReader R = new StreamReader(BASE);
		return R.ReadToEnd();
	}
}

And you can use this method in this way:

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());
}

Solution 8 - .Net

This sample shows how to read a string from a MemoryStream, in which I've used a serialization (using DataContractJsonSerializer), pass the string from some server to client, and then, how to recover the MemoryStream from the string passed as parameter, then, deserialize the MemoryStream.

I've used parts of different posts to perform this sample.

Hope that this helps.

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
    }
}

Solution 9 - .Net

Why not make a nice extension method on the MemoryStream type?

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;
		}
	}
}

Of course, be careful when using these methods in conjunction with the standard ones. :) ...you'll need to use that handy streamLock if you do, for concurrency.

Solution 10 - .Net

A slightly modified version of Brian's answer allows optional management of read start, This seems to be the easiest method. probably not the most efficient, but easy to understand and use.

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

Solution 11 - .Net

I need to integrate with a class that need a Stream to Write on it:

XmlSchema schema;
// ... Use "schema" ...

var ret = "";

using (var ms = new MemoryStream())
{
    schema.Write(ms);
    ret = Encoding.ASCII.GetString(ms.ToArray());
}
//here you can use "ret"
// 6 Lines of code

I create a simple class that can help to reduce lines of code for multiples use:

public static class MemoryStreamStringWrapper
{
    public static string Write(Action<MemoryStream> action)
    {
        var ret = "";
        using (var ms = new MemoryStream())
        {
            action(ms);
            ret = Encoding.ASCII.GetString(ms.ToArray());
        }

        return ret;
    }
}

then you can replace the sample with a single line of code

var ret = MemoryStreamStringWrapper.Write(schema.Write);

Solution 12 - .Net

Only use method Convert.ToBase64String

Convert.ToBase64String(inputStream.ToArray());

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBrianView Question on Stackoverflow
Solution 1 - .NetBrianView Answer on Stackoverflow
Solution 2 - .NetCodererView Answer on Stackoverflow
Solution 3 - .NetBrianView Answer on Stackoverflow
Solution 4 - .NetDarren KoppView Answer on Stackoverflow
Solution 5 - .NetSadjad KhazaieView Answer on Stackoverflow
Solution 6 - .NetArek BalView Answer on Stackoverflow
Solution 7 - .NetMehdi KhademlooView Answer on Stackoverflow
Solution 8 - .NetSebastian FerrariView Answer on Stackoverflow
Solution 9 - .NetAlexandruView Answer on Stackoverflow
Solution 10 - .NetJamesView Answer on Stackoverflow
Solution 11 - .NetRiccardo BassilichiView Answer on Stackoverflow
Solution 12 - .NetHarlin AceroView Answer on Stackoverflow