When I was studying WINDOWS core programming, I wrote two versions of a small program mentioned by master JEFFREY to compare performance. The original requirements of this program are as follows: in the descending order of a large file, that is, turning the header of a file into the end and the end into the header.
There are many methods to use. Here we use two methods to compare them, mainly to highlight the benefits of using memory ing files. The two methods are: Memory ing file methods, i/O read/write cache method.
The first method is to create a memory ing file object, map the object to the address space of the Process, read the file content, and write the file in reverse order.
The second method is to read the file content into a large buffer zone, then write the file in reverse order, delete the original file in the middle, and then write again.
Write the program as follows:
The first method,Memory ing file Mode:
BOOL FileReverse (PCTSTR pszPathName)
{
HANDLE hFile = CreateFile (pszPathName, GENERIC_WRITE | GENERIC_READ, 0, NULL
, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
If (hFile = INVALID_HANDLE_VALUE)
{
Printf ("File cocould not be opened .");
Return FALSE;
}
DWORD dwFileSize = GetFileSize (hFile, NULL );
HANDLE hFileMap = CreateFileMapping (hFile, NULL, PAGE_READWRITE, 0,
DwFileSize + sizeof (char), NULL );
If (hFileMap = NULL ){
CloseHandle (hFile );
Return FALSE;
}
PVOID pvFile = MapViewOfFile (hFileMap, FILE_MAP_WRITE, 0, 0 );
If (pvFile = NULL ){
CloseHandle (hFileMap );
CloseHandle (hFile );
Return FALSE;
}
PSTR pchAnsi = (PSTR) pvFile;
PchAnsi [dwFileSize/sizeof (char)] = 0;
_ Strrev (pchAnsi );
PchAnsi = strchr (pchAnsi, '/N ');
While (pchAnsi! = NULL ){
* PchAnsi ++ = '/R ';
* PchAnsi ++ = '/N ';
PchAnsi = strchr (pchAnsi, '/N ');
}
UnmapViewOfFile (pvFile );
CloseHandle (hFileMap );
SetFilePointer (hFile, dwFileSize, NULL, FILE_BEGIN );
SetEndOfFile (hFile); // you do not need to write it.
CloseHandle (hFile );
Return TRUE;
}
Method 2,Cache:
BOOL FileReverseNoMap (PCTSTR pszPathName)
{
HANDLE hFile = CreateFile (pszPathName, GENERIC_WRITE | GENERIC_READ, 0, NULL
, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
If (hFile = INVALID_HANDLE_VALUE)
{
Printf ("File cocould not be opened .");
Return FALSE;
}
DWORD dwFileSize = GetFileSize (hFile, NULL );
// CloseHandle (hFile );
Char * readBuf = new char [dwFileSize + 1];
DWORD nRead = 0, nRet = 0;
While (nRead <dwFileSize ){
If (ReadFile (hFile, readBuf + nRead, dwFileSize-nRead, & nRet, NULL) = TRUE)
{
NRead + = nRet;
}
Else
{
Printf ("Can read the file! ");
CloseHandle (hFile );
}
}
PSTR pchAnsi = (PSTR) readBuf;
PchAnsi [dwFileSize/sizeof (char)] = 0;
_ Strrev (pchAnsi );
PchAnsi = strchr (pchAnsi, '/N ');
While (pchAnsi! = NULL ){
* PchAnsi ++ = '/R ';
* PchAnsi ++ = '/N ';
PchAnsi = strchr (pchAnsi, '/N ');
}
CloseHandle (hFile );
DeleteFile (pszPathName );
HANDLE hWriteFile = CreateFile (pszPathName, GENERIC_WRITE | GENERIC_READ, 0, NULL
, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
WriteFile (hWriteFile, readBuf, dwFileSize, & nRet, NULL );
CloseHandle (hWriteFile );
Delete readBuf;
Return TRUE;
}
The comparison result is as follows:
File size (byte) |
1 method time (MS) |
2 method time (MS) |
25416 |
0 |
0 |
101664 |
0 |
0 |
406656 |
0 |
10 |
1219968 |
10 |
30 |
3202416 |
21 |
100 |
9607248 |
80 |
551 |
67250736 |
581 |
5568 |
The CPU of the machine I tested is a notebook with a memory of 1.5 MB in the xunchi.
Through the above test, we can see the advantages of using memory ing files. The larger the file memory, the more obvious this advantage is. The main reason is:
The memory ing file directly maps the file address to the address space of the process, so the operation file is equivalent to the operation in the memory, saving the time for reading and writing I/O; the second method is to do this (READFILE, WRITEFILE). This process is very slow.