Hi,
Thanks for your great study. I have done some study too (for my application) from a coder point of view. It appears that the extra time is spent when you close a file and only when you have perform at least 3 reads . It seems very weird but here is a small C++ which exibit the problem (the program is useless, and I know that you can perform the three reads in one function call, but it is just a test program to demonstrate the problem):
Code: Select all
#include <windows.h>
#include <stdio.h>
#include <time.h>
int main(int argc, char* argv[])
{
srand( (unsigned)time( NULL ) );
if (argc != 2)
{
printf ("Syntax: %s FileName\n", argv[0]);
exit (0);
}
char buffer1[256];
char* buffer2 = new char[256];
char* buffer3 = new char[256];
for (int i=0; i<20; ++i)
{
//Open the file
HANDLE hFile = CreateFile(argv[1],
GENERIC_READ,
FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == NULL)
{
printf ("Cannot open file\n");
continue;
}
DWORD pos = ((double)rand() * GetFileSize(hFile, NULL))/RAND_MAX;
//Some reading
DWORD read;
SetFilePointer(hFile, pos, NULL, FILE_BEGIN);
ReadFile (hFile, buffer1, 16, &read, NULL);
ReadFile (hFile, buffer2, 16, &read, NULL);
ReadFile (hFile, buffer3, 16, &read, NULL);
//Now the fun part: closing the file !
DWORD start = GetTickCount();
CloseHandle (hFile);
printf ("Close after read at %d: %d\n", pos, GetTickCount() - start);
}
return 1;
}
When you execute this program, you will see that the close function takes 1000ms nearly every time (if the file is big enough otherwise some parts are in the cache and it is instantaneous). If you remove a ReadFile, then the close function is instantaneous every time!
I think that I have found a workaround, it is just to create a file mapping (without using it).
So just after openig the file and getting the file handle, I have just added the folowing line:
m_hFileMap = CreateFileMapping((HANDLE)m_hFile, NULL, PAGE_READONLY, 0,0,NULL);
and I just close it just before closing my file:
CloseHandle (m_hFileMap);
Except for this two added lines, my program is not modified and is as fast as before this @#{¤$µ^ patch.