I am using c# 4.0 and every so often I come across a method in the .NET Common Library, or some other library, that has a signature like the following (e.g. Socket.Receive, Stream.Read, etc)
int DoSomethingSuperClever(byte[] buffer, int offset, int count)
The intention is always that you pass it in a buffer and it fills that buffer up to the maximum number of bytes you specify in the count argument (from the given offset) and returns exactly how many bytes it has really managed to fill in.
This is my, super naive, way of dealing with this situation:
var data = new byte[0];
var buffer = new byte[1024];
int read;
while ((read = something.DoSomethingSuperClever(buffer,
0,
buffer.Length)) > 0)
{
int origLength = data.Length;
var temp = new byte[origLength + read];
Array.Copy(data, temp, data.Length);
Array.Copy(buffer, 0, temp, origLength, read);
data = temp;
}
return data;
I think that is pretty rubbish because of all the array creations but it does the job correctly at least I suppose.
I wondered about having a List<byte>, adding to it then doing ToArray at the end…
Of course, I cannot just call AddRange because then if read was less than the length of the buffer I would get junk appended (as AddRange doesn’t accept a length argument it will always add the entire collection). So then I think to go with that approach I would end up with a for loop and loads of Add calls but surely that is even worse than the array copy isn’t it?
So, experts, what is the most efficient way that I should be dealing with these types of calls?
I’d use a
MemoryStreaminstead of abyte[]:Depending on the source of your
somethingobject you might want to adjust the buffer size to be more efficient.