好吧,这个问题确实是一个挑战!
背景
我正在从事一个涉及大于正常数字的基于算术的项目。我是新手,我将使用 4 GB 上限文件大小的最坏情况情景(我什至希望将其扩展到 5 GB 上限,因为我之前看到文件大小大于 4 GB - 特别是图像 *. iso 文件)
一般问题
现在,我将应用计算的算法目前并不重要,但加载和处理如此大量的数据 - 数字 - 才是重要的。
- A
System.IO.File.ReadAllBytes(String)
只能读取 2 GB 的文件数据上限,所以这是我的第一个问题 - 我将如何加载和/或配置访问内存,这样的文件大小 - 两倍,如果不是更多? - 接下来,我正在编写自己的类来将“流”或字节数组视为一个大数字,并添加多个运算符方法来执行十六进制算术,直到我
System.Numerics.BigInteger()
在线阅读该类 - 但是没有BigInteger.MaxValue
而且我只能一次最多加载 2 GB 的数据,我不知道它的潜力是什么BigInteger
——即使与我正在编写的对象相比Number()
(它确实具有我想要的最小潜力)。可用内存和性能也存在问题,尽管我不太关心速度,而是成功地完成了这个实验过程。
概括
- 我应该如何加载 4-5 GB 的数据?
- 加载后的数据应该如何存储和处理?坚持
BigInteger
还是完成我自己的Number
课程? - 我应该如何在运行时处理如此大量的内存而不会耗尽内存?我将像处理任何其他数字而不是字节数组一样处理 4-5 GB 的数据 - 执行诸如除法和乘法之类的算术运算。
PS 根据保密协议,我不能透露有关该项目的太多信息。;)
对于那些希望从我的 Number 对象中查看每个字节数组加法器(C#)的示例运算符的人:
public static Number operator +(Number n1, Number n2)
{
// GB5_ARRAY is a cap constant for 5 GB - 5368709120L
byte[] data = new byte[GB5_ARRAY];
byte rem = 0x00, bA, bB, rm, dt;
// Iterate through all bytes until the second to last
// The last byte is the remainder if any
// I tested this algorithm on smaller arrays provided by the `BitConverter` class,
// then I made a few tweeks to satisfy the larger arrays and the Number object
for (long iDx = 0; iDx <= GB5_ARRAY-1; iDx++)
{
// bData is a byte[] with GB5_ARRAY number of bytes
// Perform a check - solves for unequal (or jagged) arrays
if (iDx < GB5_ARRAY - 1) { bA = n1.bData[iDx]; bB = n2.bData[iDx]; } else { bA = 0x00; bB = 0x00; }
Add(bA, bB, rem, out dt, out rm);
// set data and prepare for the next interval
rem = rm; data[iDx] = dt;
}
return new Number(data);
}
private static void Add(byte a, byte b, byte r, out byte result, out byte remainder)
{
int i = a + b + r;
result = (byte)(i % 256); // find the byte amount through modulus arithmetic
remainder = (byte)((i - result) / 256); // find remainder
}