使用 Take() 从字节数组中获取字节,在 Take() 之后无法转换回 byte[]

Using Take() to grab bytes out of a byte array, having trouble converting back to byte[] after the Take()

byte[] result = memStream.ToArray();                              
memStream.Close();
byte[] temp = result.Take(255);
var str = System.Text.Encoding.Default.GetString(temp);

以上在 result.Take(255); 行失败。它说我无法将 IEnumerable 转换为 byte[],并询问我是否缺少转换。

我是 C# 新手,不太确定该怎么做。

Take() returns枚举器对象,当你枚举它时执行:

那不是一个数组,所以你不能将它分配给对字节数组的引用。但是,使用 LINQ,您可以采用任何序列,并通过调用其 ToArray() 方法 将其 转换为适当类型的数组:

byte[] temp = result.Take(255).ToArray();

ToArray() 枚举来自 Take(255) 的结果,将结果放在一个新数组中,returns 数组。

这有点令人困惑,因为您可以枚举一个数组,就像您可以枚举从 Take(255) 获得的东西一样——但是您可以枚举很多东西。这只是它们共同的一种行为,但它们实际上是非常不同的对象。

您可以将其中之一分配给 IEnumerable<byte>:

IEnumerable<byte> a = result.Take(255);
IEnumerable<byte> b = result.Take(255).ToArray();

...因为这是他们真正的共同点。

您的代码出错的原因是 .Take(result) returns 一个 IEnumerable<byte> 类型,而您正试图将其分配给 byte[] 数组。 .Take() 是一种 LINQ 方法,这通常是所有 LINQ 方法用于链接目的的工作方式(例如 result.Skip(5).Take(10))。

.ToArray() 方法采用 IEnumerable<T> 结果并将其转换为 T[]。因此,将 .ToArray() 添加到您的行将解决您的问题:

byte[] temp = result.Take(255).ToArray();

与其使用 .Take() 然后再创建另一个数组,您可能会发现它的性能更高:

byte[] temp = new byte[255]
Array.Copy(result, temp, 255);

原因是因为 .ToArray() 不知道结果数组需要多大,所以它必须选择一些相对较小的大小,随着更多项目被读入,它必须调整大小以扩大产能。在数组大到足以存储所有项目之前,这可能会发生数十次,具体取决于项目的数量。