好的,这个问题确实是一个挑战!
我正在研究一个涉及大于正常数字的基于算术的项目。我是新的,我将使用4 GB封装文件大小的最坏情况 - (我正在跳跃甚至将其扩展到5GB上限,因为我之前看到的文件大小超过4 GB - 特别是图像*。 iso文件)
现在,我将应用计算的算法此刻无关紧要,但加载和处理如此大量的数据 - 数字 - 可以。
System.IO.File.ReadAllBytes(String)
只能读取2 GB的文件数据上限,所以这是我的第一个问题 - 如何加载和/或配置访问内存,这样的文件大小 - 两倍多,如果不是更多? System.Numerics.BigInteger()
类 - 但是没有BigInteger.MaxValue
并且我一次只能加载最多2 GB的数据,我不知道BigInteger
的潜力是什么 - 甚至与我写的对象相比叫Number()
(确实有我想要的最小潜力)。可用内存和性能也存在问题,但我并不关心速度,而是成功完成了这个实验过程。BigInteger
或完成我自己的Number
课程?根据非披露协议,我无法透露有关该项目的太多信息。 ;)
对于那些希望从我的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
}
答案 0 :(得分:6)
通常,您可以使用流式API(原始二进制文件(Stream
)或某些协议阅读器(XmlReader
,StreamReader
等)处理大型文件。在某些情况下,这也可以通过内存映射文件来完成。这里的关键点是你一次只能查看文件的一小部分(中等大小的数据缓冲区,逻辑“行”或“节点”等等 - 取决于场景)。
这个奇怪的地方是你想要以某种方式直接映射到某种形式的大数字。坦率地说,我不知道在没有更多信息的情况下我们如何能够提供帮助,但如果你正在处理这个大小的实际数量,我认为除非二进制协议使得你要努力那方便。并且“执行诸如除法和乘法之类的算术”对于原始数据是没有意义的;只有定义了自定义操作的解析数据才有意义。
另外:请注意,在.NET 4.5中,您可以翻转配置开关以扩展阵列的最大大小,超过2GB限制。它仍然有限制,但是:它有点大。不幸的是,元素的最大数量仍然相同,因此如果您使用的是byte[]
数组,它将无济于事。但是,如果您使用SomeCompositeStruct[]
,您应该可以获得更高的使用率。见gcAllowVeryLargeObjects
答案 1 :(得分:3)
答案 2 :(得分:0)
FileStream
是你的开始。
如果你没有足够的内存(它应该至少比我认为的最大数量大4倍),你将需要使用硬盘。因此,将所有数据放入内存中,您宁愿加载部分数据,进行一些计算并将其写回硬盘。