我正在使用c#4.0,我经常遇到.NET公共库或其他库中的方法,它具有如下的签名(例如Socket.Receive,Stream.Read等)
int DoSomethingSuperClever(byte[] buffer, int offset, int count)
Run Code Online (Sandbox Code Playgroud)
目的始终是在缓冲区中传递它,并将缓冲区填充到您在count参数中指定的最大字节数(来自给定的偏移量),并准确返回它实际设法填充的字节数.
这是处理这种情况的超级天真的方式:
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;
Run Code Online (Sandbox Code Playgroud)
我认为这是非常垃圾,因为所有的阵列创作,但至少我认为它正确地完成了工作.
我想知道有一个List<byte>,加入它然后在最后做ToArray ...
当然,我不能只调用AddRange,因为如果读取小于缓冲区的长度,我会附加垃圾(因为AddRange不接受长度参数,它将始终添加整个集合).那么我认为采用这种方法我会最终得到一个for循环和加载的Add调用但肯定比数组副本更糟糕呢?
那么,专家们,我应该处理这些类型的呼叫的最有效方法是什么?
那么,专家们,我应该处理这些类型的呼叫的最有效方法是什么?
一个简单的方法是一次将所有内容写入MemoryStream一个块,然后使用MemoryStream.ToArray.让它处理缓冲区大小调整等.
MemoryStream ms = new MemoryStream();
while ((read = something.DoSomethingSuperClever(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
Run Code Online (Sandbox Code Playgroud)
(顺便说一句,我通常会有比1K更大的缓冲区.显然这取决于你的用例,但我通常默认为8,16或32K.)