一部分来自《Windows核心编程》,自己修改了一些地方:
/*---------------------------------------------------
*用内存映射文件来处理大文件
*程序功能:计算一个二进制文件中包含值为0的字节的个数
*时间:2012/08/03
*-------------------------------------------------*/
#ifndef _UNICODE
#define _UNICODE
#endif
#include <iostream>
using namespace std;
#include <windows.h>
#include <tchar.h>
__int64 CountOfZeros(PTSTR stPath)
{
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);
HANDLE hFile = CreateFile(
stPath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,//Access is intended to be sequential from beginning to end. The system can use this as a hint to optimize file caching.
NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
DWORD dwError = GetLastError();
MessageBox(NULL, TEXT("CreateFile failed!"), TEXT("warn"), MB_OK);
return -1;
}
HANDLE hFileMap = CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
0, //The high-order DWORD of the maximum size of the file mapping object.
0,//The low-order DWORD of the maximum size of the file mapping object. 0表示原始大小
NULL);
if (!hFileMap)
{
MessageBox(NULL, TEXT("CreateFileMapping failed!"), TEXT("warn"), MB_OK);
return -1;
}
DWORD dwFileSizeHigh;
__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize += ((__int64)dwFileSizeHigh<<32);
CloseHandle(hFile);//we need no more
__int64 qwFileOffset = 0, qwNumOf0s = 0;
while (qwFileSize>0)
{
DWORD dwBytesInBlock = sinf.dwAllocationGranularity;
if (qwFileSize<sinf.dwAllocationGranularity)
{
dwBytesInBlock = (DWORD)qwFileSize;
}
PBYTE pbFile = (PBYTE)MapViewOfFile(
hFileMap,
FILE_MAP_READ,
(DWORD)(qwFileOffset >> 32),//dwFileOffsetHigh
(DWORD)(qwFileOffset & 0xffffffff),//dwFileOffsetLow
dwBytesInBlock);//dwNumberOfBytesToMap
for (DWORD dwByte=0; dwByte<dwBytesInBlock; dwByte++)
{
if (pbFile[dwByte == 0])
{
qwNumOf0s++;
}
}
UnmapViewOfFile(pbFile);
qwFileOffset += dwBytesInBlock;
qwFileSize -= dwBytesInBlock;
}
CloseHandle(hFileMap);
return qwNumOf0s;
}
int _tmain(int argc, wchar_t *argv[], wchar_t *envp[])
{
wchar_t stPath[100];
char stPath2[100];
cout << "Please input the File Path:" << endl;
cin.getline(stPath2, 99);
int iLen = MultiByteToWideChar(
CP_ACP, //Code page to use in performing the conversion,here CP_ACP mean the system default Windows ANSI code page
0, //Flags indicating the conversion type, we do not need
stPath2, //source string path
-1, //source string length, -1 represent that the function will compute it
stPath, //Pointer to a buffer that receives the converted string
100); //Size, in characters, of the buffer indicated by lpWideCharStr
cout << "Computing..." << endl;
cout << "The number of zeros in the file is " << std::hex << "0x" << CountOfZeros((PTSTR)stPath);
cout << endl;
return 0;
}