您的位置:首页 > 其它

内存映射文件处理大文件

2012-08-03 15:56 316 查看
一部分来自《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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: