我有大量的CT rawdata文件,最大可能超过20到30GB。对于我们当前部门中的大多数计算机,我们最多只有3GB。但是为了处理数据,我们需要查看所有可用数据。当然,我们可以通过读写函数顺序遍历数据来实现这一点。但有时需要将一些数据保存在内存中。
目前我有自己的内存管理,我创建了一个所谓的MappableObject。每个rawdatafile包含20000个结构,每个结构显示不同的数据。每个MappableObject都引用文件中的一个位置。
在C#中,我创建了一个部分工作的机制,如果需要,它会自动打开和取消映射数据。从几年前我就知道了MemoryMappedFiles,但是在.NET 3.5中我拒绝使用它,因为我在.NET 4.0中知道它可以原生使用。
所以今天我尝试了MemoryMappedFiles,发现不可能分配多少内存。如果我有一个32位系统,并且我想分配20GB,由于超出逻辑地址空间的大小,它不起作用。这对我来说是清楚的。
但有没有办法像我一样处理这么大的文件?我还有什么机会?你们是如何解决这些问题的?
由于 马丁
答案 0 :(得分:3)
我所知道的唯一限制是您可以映射的文件的最大视图的大小,该视图受地址空间的限制。内存映射文件可能大于地址空间。 Windows需要在进程的地址空间的连续块中映射文件视图,因此最大映射的大小等于最大空闲地址空间块的大小。文件系统本身强加了对文件总大小的唯一限制。
答案 1 :(得分:2)
“内存映射”,您无法将20千兆字节映射到2千兆字节的虚拟地址空间。在32位操作系统上获得500 MB是非常棘手的。请注意,除非您需要对文件数据进行大量随机访问,否则它不是是一个很好的解决方案。当你必须对视图进行分区时,哪个应该很难。通过常规文件的顺序访问是非常适度的内存使用。还要注意从MMF编组数据的成本,你仍然需要支付托管结构的副本或编组成本。
答案 2 :(得分:1)
你仍然可以按顺序读取文件,你只能在内存中存储2GB以上的数据。
您可以一次映射文件的块,最好是块结构的倍数。
例如。文件是32GB。内存映射一次32MB的文件并解析它。一旦你到达那32MB的末尾,映射下一个32MB的文件并继续,直到你到达文件的末尾。
我不确定最佳映射大小是什么,但这是一个如何完成它的示例。
答案 3 :(得分:0)
你是对的。我首先尝试使用没有文件的memorymapped文件。在那里它不起作用。如果我有一个现有的文件。我可以映射我想要的内存。我想在没有真实文件的情况下使用MemoryMappedFiles的原因是它应该在流处理时自动删除。 MemoryMappedFile不支持此功能。
我现在看到的是我可以执行以下操作来获得预期结果:
// Create the stream
FileStream stream = new FileStream(
"D:\\test.dat",
FileMode.Create,
FileAccess.ReadWrite,
FileShare.ReadWrite,
8,
FileOptions.DeleteOnClose // This is the necessary part for me.
);
// Create a file mapping
MemoryMappedFile x = MemoryMappedFile.CreateFromFile(
stream,
"File1",
10000000000,
MemoryMappedFileAccess.ReadWrite,
new MemoryMappedFileSecurity(),
System.IO.HandleInheritability.None,
false
);
// Dispose the stream, using the FileOptions.DeleteOnClose the file is gone now
stream.Dispose();
至少在查看第一个结果时,我看起来很好。
谢谢。