windows 内存映射文件例子

//采用内存映射文件机制把test.txt中的内容复制到一个新的NewTest.txt(也是新建的)中 ,注意test.txt这个文件特别大,2G左右,主要是为了解决内存不足问题,采用内存映射文件机制,实现对大文件的处理
#include <windows.h>
#include <iostream>
using namespace std ;


#pragma comment(lib, "winmm.lib ")
int _tmain( int argc , _TCHAR * argv[] )
{
   
	DWORD start = timeGetTime() ;

	LARGE_INTEGER litmp;
    	LONGLONG Qpart1,Qpart2;
   	double dfMinus,dfFreq,dfTime;
     
    	//获得计时器的时钟频率
    	QueryPerformanceFrequency(&litmp);
    	dfFreq = (double)litmp.QuadPart;
	QueryPerformanceCounter(&litmp);
	Qpart1 = litmp.QuadPart; //开始计时

	// 打开目标文件
	//HANDLE hFile = CreateFile(( LPCWSTR) ".\\Test\\test.txt" , 
	//HANDLE hFile = CreateFile( L"\\Test\\test.txt" ,		//注意如果写成这样是不对的,必须是".\\Test\\test.txt"而不是"\\Test\\test.txt"																									
	HANDLE hFile = CreateFile( L".\\Test\\test.txt" , 		//注意要是LPCWSTR则不对,本人也不知道什么原因,希望有人告诉我

		GENERIC_READ , 
		FILE_SHARE_READ | FILE_SHARE_WRITE , 
		NULL , 
		OPEN_ALWAYS ,		// 如果不存在,则创建
		FILE_ATTRIBUTE_NORMAL , 
		NULL ) ;
	if ( hFile == INVALID_HANDLE_VALUE )
		return GetLastError() ;
	
	// 创建文件映射内核对象


	HANDLE hMapFile = CreateFileMapping( hFile ,
		NULL , 
		PAGE_READONLY , 
		0 , 0 ,
		NULL ) ;
	if ( hMapFile == NULL )
	{
		CloseHandle( hFile) ;
		
		return GetLastError() ;
	}


	BYTE * pMapAddr = (BYTE * ) MapViewOfFile( hMapFile ,
		FILE_MAP_READ , 
		0 , 0 ,
		NULL ) ;


	cout<< pMapAddr <<endl ;


	// 创建一个新的文件,用于保存修改后的值。
	// 创建一个新的文件
	
	//HANDLE hNewFile = CreateFile( (LPCWSTR)"NewTest.txt" ,
	HANDLE hNewFile = CreateFile( L".\\Test\\NewTest.txt" ,
	//HANDLE hNewFile = CreateFile( (LPCWSTR)"1.txt",
		GENERIC_READ | GENERIC_WRITE ,
		FILE_SHARE_READ| FILE_SHARE_WRITE ,
		NULL , 
		CREATE_ALWAYS ,
		FILE_ATTRIBUTE_NORMAL ,
		NULL ) ;
	if ( hNewFile == INVALID_HANDLE_VALUE )
		return GetLastError() ;
	// 创建一个新的内存映射对象
	HANDLE hNewMapFile = CreateFileMapping( hNewFile, 
		NULL,
		PAGE_READWRITE ,
		0 , 1000 ,		// 注意此处若不填写大小,则是失败的。
		NULL ) ;
       /* 调用CreateFileMapping的时候GetLastError的对应错误
  	* ERROR_FILE_INVALID     如果企图创建一个零长度的文件映射, 应有此报
   	* ERROR_INVALID_HANDLE   如果发现你的命名内存空间和现有的内存映射, 互斥量, 信号量, 临界区同名就麻烦了
   	* ERROR_ALREADY_EXISTS   表示内存空间命名已经存在
   	*/
	long tmp = GetLastError() ;
	if ( tmp == ERROR_FILE_INVALID )
		cout<<"tmp1="<<tmp<<endl ;
	if ( tmp == ERROR_INVALID_HANDLE )
		cout<<"tmp2="<<tmp<<endl ;
	if ( tmp == ERROR_ALREADY_EXISTS )
		cout<<"tmp3="<<tmp<<endl ;
	if ( hNewMapFile == NULL )
	{
		cout<<hNewFile<<endl ;
		CloseHandle( hFile) ;


		cout<<hNewMapFile<<endl ;
	
		return GetLastError() ;
	}
	BYTE * pNewMapAddr = ( BYTE *) MapViewOfFile( hNewMapFile,
		FILE_MAP_WRITE ,
		0 , 0 , 0) ;
	cout<<"pNewMapAddr"<<pNewMapAddr<<endl ;		//由于现在创建的hNewMapFile为空,所以此时没有显示的内容。


	cout<<endl ; 


	int i = 0 ;
	while ( pMapAddr[i] != '\0')
	{
		//pNewMapAddr[i++] = pMapAddr[i++] ; // 两次i++,故而导致错误。
		pNewMapAddr[i] = pMapAddr[i] ;
		i++ ;
	}


	cout<<pNewMapAddr<<endl ;


	UnmapViewOfFile( pMapAddr ) ;
	UnmapViewOfFile( pNewMapAddr ) ;


	CloseHandle( hNewMapFile) ;
	CloseHandle( hNewFile) ;




	CloseHandle( hMapFile) ;
	CloseHandle( hFile ) ;
	
	QueryPerformanceCounter(&litmp);
   	Qpart2 = litmp.QuadPart; //终止计时
   	dfMinus = (double)(Qpart2 - Qpart1);//计算计数器值
  	dfTime = dfMinus / dfFreq;//获得对应时间,单位为秒 你可以乘1000000精确到毫秒级(us)
   	printf( " dfTime = %ld\n " , dfTime ) ;

 	DWORD finish = timeGetTime() ;
   	DWORD subtract = finish - start ; 
   	printf( " sub = %ld\n " , subtract ) ;
 
   return 0;
}

你可能感兴趣的:(windows 内存映射文件例子)