使用標誌FILE_FLAG_IO_BUFFERING讀取一組沒有緩衝的文件(跳過文件緩存)應該比正常讀取(不使用此標誌)更快。更快的原因是'無緩衝'機制會跳過系統文件緩存並直接讀入應用程序的緩衝區。
應用程序運行在冷環境中(磁盤碎片整理,機器重新啓動後),以便系統文件緩存在運行前不會與相關文件一起緩存。
這是關於這些API和標誌的msdn文檔。
FILE_FLAG_IO_BUFFERING減慢同步讀取操作
但是,我體驗到完全不同的表現行爲。在使用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;
}
PL輕鬆地分享你的想法,因爲你認爲這段代碼的運行速度比不使用FILE_FLAG_NO_BUFFERING時慢。謝謝。
如果你總是按順序閱讀,你可以嘗試添加'FILE_FLAG_SEQUENTIAL_SCAN'標誌,看看它是否有幫助。 –
當你跳過緩存時,你也會跳過它擁有的那個美妙的選項,能夠將整個軌道讀入緩存。這是非常便宜的,因爲驅動器頭已經位於正確的位置,這是免費的數據。 –