Change From ms.Write(ms2.GetBuffer(), (int)ms.Length, (int)ms2.Length);
To
ms.Write(ms2.GetBuffer(), 0, (int)ms2.Length);
Question
I'm trying to append the contents of one memory stream to the contents of another, knowing that both memorystream contain UTF8-encoded data, and get a UTF8 string back when I convert the combined memorystream back. But it's not working => the second memorystream is being appended as garbage (or at least, it's not coming back out via the StreamReader). What could be going on?
I have the following linqpad script set up that reproduces my issue:
string one = "first memorystream";
string two = ", and the second";
MemoryStream ms = new MemoryStream();
MemoryStream ms2 = new MemoryStream();
byte[] oneb = Encoding.UTF8.GetBytes(one);
byte[] twob = Encoding.UTF8.GetBytes(two);
ms.Write(oneb, 0, oneb.Length);
ms2.Write(twob, 0, twob.Length);
ms.Length.Dump();
ms2.Length.Dump();
ms.Write(ms2.GetBuffer(), (int)ms.Length, (int)ms2.Length);
ms.Length.Dump();
ms.Position = 0;
StreamReader rdr = new StreamReader(ms, Encoding.UTF8);
rdr.ReadToEnd().Dump();
The result is:
18
16
34
first memorystream□□□□□□□□□□□□□□□□
The question, then, is why not "first memorystream, and the second"?
What I am doing wrong?
Solution
Change From ms.Write(ms2.GetBuffer(), (int)ms.Length, (int)ms2.Length);
To
ms.Write(ms2.GetBuffer(), 0, (int)ms2.Length);
OTHER TIPS
Second argument of Write is position in source buffer - so it contains 0 as it is explicitly after end of the second stream.
public abstract void Write( byte[] buffer, int offset, int count )
offsetType: System.Int32 The zero-based byte offset in buffer at which to begin copying bytes to the current stream.
Fix - pass 0 for offset since you want to copy from the beginning of the buffer:
ms.Write(ms2.GetBuffer(), 0, (int)ms2.Length);
Ran it in LinqPad, all good; read the comment below for better solution understanding...
string one = "first memorystream";
string two = ", and the second";
MemoryStream ms = new MemoryStream();
MemoryStream ms2 = new MemoryStream();
byte[] oneb = Encoding.UTF8.GetBytes(one);
byte[] twob = Encoding.UTF8.GetBytes(two);
ms.Write(oneb, 0, oneb.Length);
ms2.Write(twob, 0, twob.Length);
ms.Length.Dump("Stream 1, Length");
ms2.Length.Dump("Stream 2, Length");
ms2.Position = 0; // <-- You have to set the position back to 0 in order to write it, otherwise the stream just continuous where it left off, the end
ms2.CopyTo(ms, ms2.GetBuffer().Length); // <-- simple "merge"
/*
* Don't need the below item anymore
*/
//ms.Write(ms2.GetBuffer(), (int)ms.Length, (int)ms2.Length);
ms.Length.Dump("Combined Length");
ms.Position = 0;
StreamReader rdr = new StreamReader(ms, Encoding.UTF8);
rdr.ReadToEnd().Dump();