If I am given a MemoryStream that I know has been populated with a String, how do I get a String back out?
use a StreamReader, then you can use the ReadToEnd method that returns a string.
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
Never quite sure if reader.close is always required. I have had issues in the past so as a rule I always do just to be on the safe side.
I would just argue your setting Position to 0 because it unnecessarily limits the function use. It states that you always want to read the string from the beginning of the stream.
EDIT: answering Alex Lyman I believe my reputation doesn't allow me to comment on answers (either that or I'm blind).
While the first comment's code nearly gets it right, it still not quite there. The return statement will prevent the reader's dispose method from being called.
So the proper method of doing this is: Public Function GetString(ByVal memStream As MemoryStream) As String Dim tReturn as String = String.Empty ' Important to reset the stream otherwise you will just get an empty string. memStream.Position = 0 Using reader As New StreamReader(memStream) tReturn = reader.ReadToEnd() End Using Return tReturn End Function
This sample shows how to read and write a string to a 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();
}
You can also use
ASCIIEncoding.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.
a slightly modified version of the first 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