使用标志 FILE_FLAG_IO_BUFFERING 读取一组没有缓冲的文件(跳过文件缓存)应该比正常读取(不使用此标志)更快。更快的原因是“无缓冲”机制将跳过系统文件缓存并直接读入应用程序的缓冲区。
应用程序在冷环境下运行(磁盘碎片整理后,机器重启后),因此系统文件缓存不会与运行前的相关文件一起缓存。
这是来自有关这些 API 和标志的 msdn 文档。
但是,我遇到了完全不同的性能行为。在使用 FILE_FLAG_IO_BUFFERING 标志创建文件句柄之后,我一个接一个地同步读取一组文件。读取这组文件所需的时间是 29 秒。如果我在不使用此标志的情况下正常读取(再次在文件缓存不保存相关文件时在应用程序的冷运行中),则所需时间约为 24 秒。
详细信息:
文件总数:1939
文件总大小(所有文件的总和):57 MB
带 FLAG_IO_NO_BUFFERING:29 秒(读取时间)
不带 FLAG_IO_NO_BUFFERING:24 秒(读取时间)
下面是实现读取的代码:
DWORD ReadFiles(std::vector<std::string> &filePathNameVectorRef)
{
long totalBytesRead = 0;
for(all file in filePathNameVectorRef)
totalBytesRead += Read_Synchronous(file);
return totalBytesRead;
}
DWORD Read_Synchronous(const char * filePathName)
{
DWORD accessMode = GENERIC_READ;
DWORD shareMode = 0;
DWORD createDisposition = OPEN_EXISTING;
DWORD flags = FILE_FLAG_NO_BUFFERING;
HANDLE handle = INVALID_HANDLE_VALUE;
DWORD fileSize;
DWORD bytesRead = 0;
DWORD bytesToRead = 0;
LARGE_INTEGER li;
char * buffer;
BOOL success = false;
handle = CreateFile(filePathName, accessMode, shareMode, NULL, createDisposition, flags, NULL);
if(handle == INVALID_HANDLE_VALUE)
return 0;
GetFileSizeEx(handle, &li);
fileSize = (DWORD)li.QuadPart;
bytesToRead = (fileSize/g_bytesPerPhysicalSector)*g_bytesPerPhysicalSector;
buffer = static_cast<char *>(VirtualAlloc(0, bytesToRead, MEM_COMMIT, PAGE_READWRITE));
if(buffer == NULL)
goto RETURN;
success = ReadFile(handle, buffer, bytesToRead, &bytesRead, NULL);
if(!success){
fprintf(stdout, "\n Error occured: %d", GetLastError());
return 0;
}
free(buffer);
RETURN:
CloseHandle(handle);
return bytesRead;
}
请分享您认为此代码运行速度比不使用 FILE_FLAG_NO_BUFFERING 时慢的原因的想法。谢谢。