According to MSDN, ReadFile can read data in two different ways: synchronously and asynchronously. I need a second one. The following code demonstrates use with an OVERLAPPED struct:
#include <windows.h> #include <stdio.h> #include <time.h> void Read() { HANDLE hFile = CreateFileA("c:\\1.avi", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if ( hFile == INVALID_HANDLE_VALUE ) { printf("Failed to open the file\n"); return; } int dataSize = 256 * 1024 * 1024; char* data = (char*)malloc(dataSize); memset(data, 0xFF, dataSize); OVERLAPPED overlapped; memset(&overlapped, 0, sizeof(overlapped)); printf("reading: %d\n", time(NULL)); BOOL result = ReadFile(hFile, data, dataSize, NULL, &overlapped); printf("sent: %d\n", time(NULL)); DWORD bytesRead; result = GetOverlappedResult(hFile, &overlapped, &bytesRead, TRUE); // wait until completion - returns immediately printf("done: %d\n", time(NULL)); CloseHandle(hFile); } int main() { Read(); }
In Windows XP, output: read: 1296651896 sent: 1296651896 done: 1296651899
This means that the ReadFile not blocked and returned imediatly for one second, while the reading process continued for 3 seconds. This is a normal asynchronous read.
But in Windows 7 and Windows 2008, I get the following results: read: 1296661205 sent: 1296661209 done: 1296661209. This is a synchronized read behavior.
MSDN says that async ReadFile can sometimes behave like synchronization (when a file is compressed or encrypted, for example). But the return value in this situation should be TRUE and GetLastError() == NO_ERROR. On Windows 7, I get FALSE and GetLastError() == ERROR_IO_PENDING. Therefore, WinApi informs me that this is an asynchronous call, but when I look at the test, I see that it is not!
I'm not the only one who found this “error”: read the comment on the MSDN ReadFile page.
So what is the solution? Somebody knows? 14 months after Denis found this strange behavior.