文件映射 遇到的问题
文件映射存储大容量的数据时,当数据超过2G时,memcpy函数会变的非常慢,高手求解? --------------------编程问答-------------------- 试试看能不能把一个文件分割成几个小文件然后多线程来拷贝? --------------------编程问答-------------------- 拷贝2g的数据量 你想多块。搞笑不是 --------------------编程问答-------------------- 还是听二楼的吧 --------------------编程问答-------------------- 对,用内存文件映射来把切割大文件.下面是我做一个作业是,老师要求有大文件切割功能,而写的一个函数来应对答大文件,希望能给你帮助,大文件切割的知识我是从<<widows 核心编程>>第十七章中学到.
DWORD En_And_De_File_Class::DE_File ( PFILE_ITEM_INFO pItem )
{
if(pItem->fill_num != 0)
{
AfxMessageBox("文件可能已损坏或非经aes加密过");
return -1;
}
// 打开目标文件
HANDLE hFile = CreateFile ( pItem->szFileName,GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,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() ;
}
//创建生产加密文件内存映像和映射内核对象
HANDLE New_hFile = CreateFile (pItem->szFileName + ".pdf", GENERIC_READ|GENERIC_WRITE, \
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL ) ;
if ( New_hFile == INVALID_HANDLE_VALUE )
return GetLastError() ;
// 创建文件内存映射内核对象
HANDLE New_hMapFile = CreateFileMapping(New_hFile,NULL,PAGE_READWRITE,0,pItem->dwLowFileSize,NULL) ;
if ( New_hMapFile == NULL )
{
CloseHandle (New_hFile) ;
return GetLastError() ;
}
DWORD dwCurAddr = 0, dwCurPart = 0 ;
LPVOID lpMapAddr = 0 ,New_lpMapAddr = 0;
Aes aes(16,(unsigned char*)"\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9\xa\xb\xc\xd\xe\xf");
// 分块循环映射文件
if(pItem->dwPartNum > 0)
{
dwCurPart = pItem->dwPartSize ;
unsigned char* lpBuffer = new unsigned char[dwCurPart];
for ( int k = 1; k <= pItem->dwPartNum; k++ )
{
lpMapAddr = MapViewOfFile ( hMapFile, FILE_MAP_READ, 0, dwCurAddr, dwCurPart ) ;
if ( lpMapAddr == NULL )
{
CloseHandle ( hMapFile ) ;
CloseHandle ( hFile ) ;
return GetLastError() ;
}
New_lpMapAddr = MapViewOfFile ( New_hMapFile, FILE_MAP_WRITE, 0, dwCurAddr, dwCurPart ) ;
if ( New_lpMapAddr == NULL )
{
CloseHandle ( New_hMapFile ) ;
CloseHandle ( New_hFile ) ;
return GetLastError() ;
}
dwCurAddr += dwCurPart ;
// 把数据写入到加密或加密缓冲区中
memcpy ( lpBuffer, lpMapAddr, dwCurPart );
//解密 (同时进行HASH操作)--->
int blocknum=(int)dwCurPart/16;
for(int i =0;i<blocknum;i++)
aes.InvCipher(lpBuffer + i * 16,lpBuffer + i * 16);
//加密或者加密(同时进行HASH操作)<----
memcpy ( New_lpMapAddr,lpBuffer, dwCurPart ) ;
FlushViewOfFile ( New_lpMapAddr, dwCurPart ) ;//将BUFFER中处理过的数据写入新文件中
UnmapViewOfFile ( New_lpMapAddr ) ;//
UnmapViewOfFile ( lpMapAddr ) ;//
}
delete [] lpBuffer ;//得加析构动态分配的内存,不然会发生内存泄露
}
//---> 当 文件块小于设定值得文件块处理, 同时当文件块长度不为 16字节的倍数时,进行尾部填充处理 <-----------
if( dwCurPart != 0 || pItem->dwPartNum == 0)
{
dwCurPart = pItem->dwLowFileSize - dwCurAddr ;//假如需要填充,那这是最后一轮加密
lpMapAddr = MapViewOfFile ( hMapFile, FILE_MAP_READ, 0, dwCurAddr, dwCurPart ) ;
if ( lpMapAddr == NULL )
{
CloseHandle ( hMapFile ) ;
CloseHandle ( hFile ) ;
return GetLastError() ;
}
New_lpMapAddr = MapViewOfFile ( New_hMapFile, FILE_MAP_WRITE, 0, dwCurAddr, dwCurPart + pItem->fill_num ) ;
if ( New_lpMapAddr == NULL )
{
CloseHandle ( New_hMapFile ) ;
CloseHandle ( New_hFile ) ;
return GetLastError() ;
}
// 把数据写入到加密或加密缓冲区中
unsigned char* lpBuffer = new unsigned char[dwCurPart+pItem->fill_num];
memcpy ( lpBuffer, lpMapAddr, dwCurPart );
//加密或者加密 (同时进行HASH操作)--->
int blocknum=(int)dwCurPart/16;
int leftnum=(int)dwCurPart%16;
int l = 0;
for(l = 0 ;l < blocknum;l++)
aes.InvCipher(lpBuffer + l * 16,lpBuffer + l * 16);
if(pItem->fill_num != 0)
aes.InvCipher(lpBuffer + l * 16,lpBuffer + l * 16);
//加密或者加密(同时进行HASH操作)<----
memcpy ( New_lpMapAddr,lpBuffer, dwCurPart ) ;
FlushViewOfFile ( New_lpMapAddr, dwCurPart ) ;//将BUFFER中处理过的数据写入新文件中
delete [] lpBuffer ;
UnmapViewOfFile ( New_lpMapAddr ) ;//
UnmapViewOfFile ( lpMapAddr ) ;//
}
CloseHandle ( New_hMapFile ) ;
CloseHandle ( New_hFile ) ;
CloseHandle ( hMapFile ) ;
CloseHandle ( hFile ) ;
return 0 ;
} --------------------编程问答-------------------- 可以考虑多线程拷贝
补充:.NET技术 , VC.NET