有许多问题询问如何在此站点上获取数组的子集,但是没有人成功地获得有关如何写入数组的答案,就好像它是byte[]
一样。
byte[] bigTargetBytes = new byte[10000];
byte[] twentyBytes = sha256.ComputeHash(sourcebytes); // size is 20 bytes,
// how do I append this to the existing array without copying, using Linq, etc?
我不想做的是有两个数组并在它们之间进行复制,因为这是与数组长度成比例的时间密集型(我的数组很长)
答案 0 :(得分:2)
我担心你必须以任何方式制作副本。我建议你使用Buffer.BlockCopy()
方法,这是最快的方法。
答案 1 :(得分:1)
目前还不清楚你想要什么,但我猜你想要一个字节数组的“视图”。在.Net 4.5中,您可以使用ArraySegment<T>
:
var a = new byte[100];
var s = new ArraySegment<Byte>(a, 9, 90);
((IList<Byte>)s)[0] = 10;
Console.WriteLine(a[9]); // writes "10"
因此,您的Write90Bytes
方法可以返回ArraySegment<Byte>
,然后您可以将其作为基础数组的视图进行操作,这将避免复制。但请注意,ArraySegment<T>
是System.ValueType
,这意味着将其投放到IList<T>
会导致拳击惩罚。
如果性能至关重要并且您需要避免复制,您可能还会考虑在不安全的上下文中使用指针,这意味着您的Write90Bytes
方法可以返回Byte*
,然后您可以索引到数组那样。
编辑:现在我看到你的编辑,你不能只是将函数中的值“返回”到数组的内存位置。您需要将原始数组作为参数传递。
编辑2:你无法做你想要的。 ComputeHash
函数返回它自己分配的数组。如果ComputeHash
将数组作为参数,那么你可以做你想做的唯一方法。考虑:
// previously defined...
byte[] bigTargetBytes = new byte[10000];
// This method doesn't really exist, but if it did it would look like this
sha256.ComputeHash(sourcebytes, bigTargetBytes, offset);
虽然在.Net中由于它是托管运行时而对内存分配有特定限制,但这是任何编程语言中的常见模式。在C / C ++开发中,有一个协议用于传递预先分配的数组,其中包含要写入的偏移量和maxlength,或者允许函数返回已分配的内存,然后您将有权释放(除非你从框架中被召回)。您不能只将值返回到现有缓冲区。
请注意,仅从ComputeHash
值分配的GC数组中复制20个字节是一项非常简单的操作,运行时处理非常有效。除非您不时对微秒级别的暂停非常敏感,否则您将不会注意到实际副本与假设实现之间的差异。