0

有很多问题询问如何在此站点上获取数组的子集,但是没有人成功获得有关如何像写入数组一样写入数组的答案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?

我不想做的是有两个数组并在它们之间进行复制,因为这与数组的长度成正比(而且我的数组很长)

4

2 回答 2

2

恐怕您必须以任何一种方式制作副本。我建议你使用Buffer.BlockCopy()最快的方法。

于 2012-12-17T21:09:09.677 回答
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>是 a System.ValueType,这意味着将其转换为IList<T>将招致拳击惩罚。

如果性能至关重要并且您需要避免复制,您还可以考虑在不安全的上下文中使用指针,这意味着您的Write90Bytes方法可以返回 aByte*并且您可以通过这种方式索引到数组中。

编辑:现在我看到了您的编辑,您不能只将函数中的值“返回”到数组的内存位置。您需要将原始数组作为参数传递。

编辑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++ 开发中,有一个协议使用,您可以传入一个预分配的数组,其中包含要写入的偏移量和最大长度,或者您允许函数返回分配的内存,然后您有责任释放 (除非您从框架中被回调)。您不能只将值返回现有缓冲区中。

但是请注意,仅从由该ComputeHash值分配的 GC 数组中复制 20 个字节是一个非常简单的操作,运行时可以非常有效地处理它。除非您不时对微秒级暂停非常敏感,否则您不会注意到实际副本和假设实现之间的差异。

于 2012-12-17T21:22:30.150 回答