我正在研究一个对大文件(直到64 GB)进行大量读写随机访问的程序。文件是专门结构化的,并且为了访问它们,我创建了一个框架;一段时间后,我尝试测试其性能,并注意到在预分配文件上,顺序写入操作太慢而无法接受。
经过多次测试,我没有使用框架(仅使用FileStream方法)复制了行为。这是(与我的硬件一起)复制问题的部分代码:

FileStream fs = new FileStream("test1.vhd", FileMode.Open);
byte[] buffer = new byte[256 * 1024];
Random rand = new Random();
rand.NextBytes(buffer);
DateTime start, end;
double ellapsed = 0.0;
long startPos, endPos;

BinaryReader br = new BinaryReader(fs);
br.ReadUInt32();
br.ReadUInt32();
for (int i = 0; i < 65536; i++)
    br.ReadUInt16();

br = null;

startPos = 0;   // 0
endPos = 4294967296;    // 4GB
for (long index = startPos; index < endPos; index += buffer.Length)
{
    start = DateTime.Now;
    fs.Write(buffer, 0, buffer.Length);
    end = DateTime.Now;
    ellapsed += (end - start).TotalMilliseconds;
}

不幸的是,这个问题似乎是无法预料的,​​因此有时“起作用”,有时却不起作用。
但是,使用Process Monitor,我捕获了以下事件:

操作结果明细
WriteFile成功偏移量:1.905.655.816,长度:262.144
WriteFile成功偏移量:1.905.917.960,长度:262.144
WriteFile成功偏移量:1.906.180.104,长度:262.144
WriteFile成功偏移量:1.906.442.248,长度:262.144
WriteFile成功偏移量:1.906.704.392,长度:262.144
WriteFile成功偏移量:1.906.966.536,长度:262.144
ReadFile SUCCESS偏移量:1.907.228.672,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常
WriteFile成功偏移量:1.907.228.680,长度:262.144
ReadFile SUCCESS偏移量:1.907.355.648,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常
ReadFile SUCCESS偏移量:1.907.490.816,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常
WriteFile成功偏移量:1.907.490.824,长度:262.144
ReadFile SUCCESS偏移量:1.907.617.792,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常
ReadFile SUCCESS偏移量:1.907.752.960,长度:32.768,I/O标志:非缓存,分页I/O,同步分页I/O,优先级:正常
WriteFile成功偏移量:1.907.752.968,长度:262.144

也就是说,在重写了将近2 GB后,FileStream.Write在每个ReadFile之后开始调用WriteFile,这个问题一直持续到过程结束;同样,问题开始的偏移量似乎是随机的。
我已经在FileStream.Write方法中进行了逐步调试,并验证了实际上是内部调用WriteFileReadFile(Win32 API)。

最后的音符;我不认为这是文件碎片的问题:我已经用contig对文件进行了碎片整理!

最佳答案

我相信这与FileStream.Write/Read和2GB的限制有关。您是在32位进程中运行此程序吗?我找不到有关此内容的任何特定文档,但这是一个MSDN forum问题,听起来很像。您可以尝试在64位进程中运行它。

但是,我同意使用内存映射文件可能是一种更好的方法。

10-06 12:18