I want to write a String to a Stream (a MemoryStream in this case) and read the bytes one by one.
stringAsStream = new MemoryStream();
UnicodeEncoding uniEncoding = new UnicodeEncoding();
String message = "Message";
stringAsStream.Write(uniEncoding.GetBytes(message), 0, message.Length);
Console.WriteLine("This:\t\t" + (char)uniEncoding.GetBytes(message)[0]);
Console.WriteLine("Differs from:\t" + (char)stringAsStream.ReadByte());
The (undesired) result I get is:
This: M
Differs from: ?
It looks like it's not being read correctly, as the first char of "Message" is 'M', which works when getting the bytes from the UnicodeEncoding instance but not when reading them back from the stream.
What am I doing wrong?
The bigger picture: I have an algorithm which will work on the bytes of a Stream, I'd like to be as general as possible and work with any Stream. I'd like to convert an ASCII-String into a MemoryStream, or maybe use another method to be able to work on the String as a Stream. The algorithm in question will work on the bytes of the Stream.
You need to reset the stream to the beginning:
This can also be done by setting the
Position
property to 0:I think it would be a lot more productive to use a
TextWriter
, in this case a StreamWriter to write to the MemoryStream. After that, as other have said, you need to "rewind" the MemoryStream using something likestringAsStream.Position = 0L;
.Note that:
Also, you don't have to create a
new UnicodeEncoding()
usually, since there's already one as a static member of the class for you to use in convenient utf-8, utf-16, and utf-32 flavors.And then, finally (as others have said) you're trying to convert the
byte
s directly tochar
s, which they are not. If I had a memory stream and knew it was a string, I'd use aTextReader
to get the string back from the bytes. It seems "dangerous" to me to mess around with the raw bytes.Try this "one-liner" from Delta's Blog, String To MemoryStream (C#).
The string will be loaded into the
MemoryStream
, and you can read from it. See Encoding.GetBytes(...), which has also been implemented for a few other encodings.You're using
message.Length
which returns the number of characters in the string, but you should be using the nubmer of bytes to read. You should use something like:You're then reading a single byte and expecting to get a character from it just by casting to
char
.UnicodeEncoding
will use two bytes per character.As Justin says you're also not seeking back to the beginning of the stream.
Basically I'm afraid pretty much everything is wrong here. Please give us the bigger picture and we can help you work out what you should really be doing. Using a
StreamWriter
to write and then aStreamReader
to read is quite possibly what you want, but we can't really tell from just the brief bit of code you've shown.After you write to the
MemoryStream
and before you read it back, you need toSeek
back to the beginning of theMemoryStream
so you're not reading from the end.UPDATE
After seeing your update, I think there's a more reliable way to build the stream:
As you can see, this code uses a StreamWriter to write the entire string (with proper encoding) out to the
MemoryStream
. This takes the hassle out of ensuring the entire byte array for the string is written.Update: I stepped into issue with empty stream several time. It's enough to call Flush right after you've finished writing.