内存映射文件 (windows许多方法用此来在进程间传送数据)
1.CreateFile
2.CreateFileMapping //对含有SEC_LARGE_PAGES标志时用户必须具有启用内存锁定页面用户权限,否则会失败
3.MapViewOfFile
4. //FlushViewOfFile //确保所做的修改已经被写入到磁盘中,如果最初是FILE_MAP_COPY,将修改页交换文件中的文件数据副本,如果是这样的话ummapviewoffile后数据丢失。可以再做个PAGE_READWRITE视图,再MoveMemory从前一视图拷到这个视图。
5.UnmapViewOfFile
6.CloseHandle(hMap);CloseHandle(hFile); //先后顺序无关,MapViewOfFile副作用是增加hFile引用计数。
对多个进程共享同一个文件映射对象来说,所有进程使用的文件映射对象的名称必须完全相同。
CreateFileMapping传入INVALID_HANDLE_VALUE时映射页交换文件,不再映射磁盘文件。
#include <Windows.h>
#include <string>
#include <iostream>
using namespace std;
bool FileReverse(const wchar_t* pcFileName)
{
BOOL bIsUnicode = false;
HANDLE hFile = CreateFileW(pcFileName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if( hFile == INVALID_HANDLE_VALUE ) //here must check, because createfilemapping can accept INVALID_HANDLE_VALUE, and different map view
{
cout<<"CreateFileW fail"<<endl;
return false;
}
DWORD dwFileSize = GetFileSize(hFile,NULL);
HANDLE hMap = CreateFileMappingW(hFile,NULL,PAGE_READWRITE,0,dwFileSize*sizeof(wchar_t),NULL);
if( hMap == NULL )
{
cout<<"CreateFileMappingW fail"<<endl;
CloseHandle(hFile);
return false;
}
PVOID pvFile = MapViewOfFile(hMap,FILE_MAP_WRITE,0,0,0);
if( pvFile == NULL )
{
cout<<"MapViewOfFile fail"<<endl;
CloseHandle(hMap);
CloseHandle(hFile);
return false;
}
int iUnicodeTestFlag = -1;
bIsUnicode = IsTextUnicode(pvFile,dwFileSize,&iUnicodeTestFlag);
if(!bIsUnicode)
{
char *pchar = (char*)pvFile;
pchar[dwFileSize/sizeof(char)] = '\0';
_strrev(pchar);
pchar = strstr(pchar,"\n\r"); //find first \r\n
while( pchar != NULL )
{
*pchar++ = '\r';
*pchar++ = '\n';
pchar = strstr(pchar,"\n\r");
}
}
else
{
wchar_t *pwchar = (wchar_t*)pvFile;
pwchar[dwFileSize/sizeof(wchar_t)] = L'\0';
if((iUnicodeTestFlag & IS_TEXT_UNICODE_SIGNATURE) != 0)
{
pwchar++;
}
_wcsrev(pwchar);
pwchar = wcsstr(pwchar,L"\n\r"); //find first \r\n
while( pwchar != NULL )
{
*pwchar++ = L'\r';
*pwchar++ = L'\n';
pwchar = wcsstr(pwchar,L"\n\r");
}
}
UnmapViewOfFile(pvFile);
CloseHandle(hMap);
//delete manuly append '\0'
SetFilePointer(hFile,dwFileSize,NULL,FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);
return true;
}
void wmain()
{
FileReverse(L"testu.txt");
}