给出
// 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
由于Array.zeroCreate
和Array.init
采用Int32
,如何创建一个可能大于Int32.MaxValue
的空数组?
答案 0 :(得分:6)
In .NET 4.5 and newer, the gcAllowVeryLargeObjects
configuration element可以创建大于2GB的单个对象,但即使这样也不会改变数量上的硬限制数组中的元素。引用备注部分:
数组中的最大元素数是UInt32.MaxValue。
对于字节数组和单字节结构数组,任何单个维度的最大索引为2,147,483,591(0x7FFFFFC7),其他类型为2,146,435,071(0X7FEFFFFF)。
我不完全确定为什么UInt32
而不是Int32
(你可以创建最小索引为Int32.MinValue
的数组,但是我&# 39;我不确定你是否能够做很多事情: - ))。
但是,使用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时,一个级别的间接可能不会导致过多的开销。
答案 1 :(得分:3)
你做不到。 .NET上一维数组的最大长度为System.Int32.MaxValue
。当值大于此限制时,您的C#代码会引发OverflowException
。等效的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))