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?

Was it helpful?

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();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top