1

给定

// r is a System.Data.IDataRecord
var blob = new byte[(r.GetBytes(0, 0, null, 0, int.MaxValue))];
r.GetBytes(0, 0, blob, 0, blob.Length);

r.GetBytes(...)返回Int64 SinceArray.zeroCreateArray.inittakeInt32如何创建一个可能大于的空数组Int32.MaxValue

4

2 回答 2

6

在 .NET 4.5 和更高版本中,gcAllowVeryLargeObjects 配置元素允许您创建大于 2GB 的单个对象,但即使这样也不会更改数组中元素数量的硬限制。引用备注部分:

数组中的最大元素数是 UInt32.MaxValue。

对于字节数组和单字节结构的数组,任何单个维度的最大索引为 2,147,483,591 (0x7FFFFFC7),其他类型的最大索引为 2,146,435,071 (0X7FEFFFFF)。

我不完全确定为什么UInt32而不是Int32(您可以在最小索引所在的位置创建数组Int32.MinValue,但我不确定您能否用它做很多事情:-))。

但是,使用该gcAllowVeryLargeObjects参数,您可以通过创建包含多个值的结构数组来创建非常大的数组 - 这会分配超过 2GB 的连续内存块:

[<Struct>]
type Quadruple<'T>(v1:'T, v2:'T, v3:'T, v4:'T) = 
  member x.V1 = v1
  member x.V2 = v2
  member x.V3 = v3
  member x.V4 = v4

let qa : Quadruple<byte>[] = Array.zeroCreate 10 

我认为这不是特别实用,但这是一种可能性。实际上,将数据拆分为数组似乎更容易。当单个阵列大约 2GB 时,一级间接可能不会导致太多开销。

于 2016-06-06T20:25:30.093 回答
3

你不能。.NET 上一维数组的最大长度为System.Int32.MaxValue. OverflowException当值大于此限制时,您的 C# 代码会引发一个。等效的 F# 代码是:

let blob =         
    let length = r.GetBytes(0, 0, null, 0, Int32.MaxValue)
    if length > int64(Int32.MaxValue) then
        raise (OverflowException())
    else
        Array.zeroCreate<byte>(int32(length))
于 2016-06-06T20:17:06.427 回答