ITPub博客

首页 > 大数据 > 数据分析 > 大数据处理方法:内存映射

大数据处理方法:内存映射

数据分析 作者:langzi2766077 时间:2013-09-18 18:36:45 0 删除 编辑

内存映射文件
题目:对一个文件使用内存映射文件
Demo:
1:创建或打开一个文件内核对象:
// Open the file for reading and writing.
HANDLE hFile = CreateFile(pszPathname, GENERIC_WRITE | GENERIC_READ, 0,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// 由于hFile即使为INVALID_HANDLE_VALUE,下面的CreateFileMapping仍然可以正常运行,
// 所以这里一定要对hFile进行检查!
if (hFile == INVALID_HANDLE_VALUE) {
chMB("File could not be opened.");
return(FALSE);
}
2:创建一个文件映射内核对象:
// Get the size of the file (I assume the whole file can be mapped).
DWORD dwFileSize = GetFileSize(hFile, NULL);
// Create the file-mapping object. The file-mapping object is 1 character
// bigger than the file size so that a zero character can be placed at the
// end of the file to terminate the string (file). Because I don't yet know
// if the file contains ANSI or Unicode characters, I assume worst case
// and add the size of a WCHAR instead of CHAR.
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE,
0,
dwFileSize + sizeof(WCHAR), // 如果该文件小于设定的大小,本函数将扩展该文件的大小,
// 使磁盘上的文件变大。这样当以后将该文件作为内存映射
// 文件使用时,物理存储器就已经存在了。
NULL f// 这个文件映射对象的名字用于与其他进程共享该对象,这里我们还用不到。
);
if (hFileMap == NULL) {
chMB("File map could not be opened.");
CloseHandle(hFile);
return(FALSE);
}
3:将文件数据映射到进程的地址空间:
当创建了一个文件映射对象之后,仍然必须让系统为文件的数据保留一个地址空间区域,
并将文件的数据作为映射到该区域的物理存储器进行提交。
// Get the address where the first byte of the file is mapped into memory.
// the return value is the starting address of the mapped view:
PVOID pvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
if (pvFile == NULL) {
chMB("Could not map view of file.");
CloseHandle(hFileMap);
CloseHandle(hFile);
return(FALSE);
}
4:既然我们通过pvFile得到了映象视图的起始地址,那么可以对视图做一些操作了:
ANSI版本:
PSTR pchANSI = (PSTR) pvFile;
UNICODE版本:
PWSTR pchUnicode = (PWSTR) pvFile;
5:从进程的地址空间中撤销文件数据的映象:
// Clean up everything before exiting.
UnmapViewOfFile(pvFile);
6:关闭文件映射对象和文件对象:
CloseHandle(hFileMap);
CloseHandle(hFile);
Definition:
HANDLE CreateFileMapping(
HANDLE hFile, // handle to file
LPSECURITY_ATTRIBUTES lpAttributes, // security
DWORD flProtect, // protection
DWORD dwMaximumSizeHigh, // high-order DWORD of size
DWORD dwMaximumSizeLow, // low-order DWORD of size
LPCTSTR lpName // object name
);
LPVOID MapViewOfFile(
HANDLE hFileMappingObject, // handle to file-mapping object
DWORD dwDesiredAccess, // access mode
DWORD dwFileOffsetHigh, // high-order DWORD of offset
DWORD dwFileOffsetLow, // low-order DWORD of offset
SIZE_T dwNumberOfBytesToMap // number of bytes to map
);
BOOL UnmapViewOfFile(
LPCVOID lpBaseAddress // starting address
);
Tips:
也可以尽量早地把对象关闭,以消除资源泄漏的可能性,如:
HANDLE hFile = CreateFile(...);
HANDLE hFileMapping = CreateFileMapping(hFile,...);
CloseHandle(hFile);
PVOID pvFile = MapViewOfFile(hFileMapping,...);
CloseHandle(hFileMapping);
// use the memory-mapped file.
UnmapViewOfFile(pvFile);

 

 


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~代码~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#include

#include

 

#include

#include

 

#define BAD_POS 0xFFFFFFFF // returned by SetFilePointer and GetFileSize

#define SUCCESS 0

using namespace std;

 

 

typedef DWORD mmf_share_mode;

typedef DWORD mmf_access_mode;

typedef DWORD mmf_flags;

 

 

int main(){

    cout<<"create memorymapfile..."<

    const char* shared_name = "testMmf";

    const char* file_name = "d:\testMmf.mmf";

    const DWORD mmf_size = 512*1024;

    //存取模式

    mmf_access_mode access_mode = (GENERIC_READ|GENERIC_WRITE);

    //共享模式

    mmf_share_mode share_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;

    //文件属性

    mmf_flags flags = FILE_FLAG_SEQUENTIAL_SCAN;//|FILE_FLAG_WRITE_THROUGH|FILE_FLAG_NO_BUFFERING;

    DWORD error_code;

    

    //创建文件

    HANDLE mmHandle =

        CreateFile(file_name,

             access_mode,

             share_mode,

             NULL,

             OPEN_ALWAYS,

             flags,

             NULL);

 

    if (mmHandle == INVALID_HANDLE_VALUE) {

        error_code = GetLastError();

        cout<<"创建mmf失败:"<

    }else{

        DWORD high_size;

        DWORD file_size = GetFileSize(mmHandle, &high_size);

        if (file_size == BAD_POS && (error_code = GetLastError()) != SUCCESS) {

            CloseHandle(mmHandle);           

            cout<<"error:"<

        }

        cout<<"create mmf sucessfully"<

 

        //assert(file_size == 0);

 

        DWORD size_high = 0;

        //创建文件映射,如果要创建内存页面文件的映射,第一个参数设置为INVALID_HANDLE_VALUE

        HANDLE mmfm = CreateFileMapping(mmHandle,

            NULL,

            PAGE_READWRITE,

            size_high,

            mmf_size,

            shared_name);

 

        error_code = GetLastError();

        if(SUCCESS != error_code){

            cout<<"createFileMapping error"<

        }else{

            if(mmfm == NULL){

                if(mmHandle != INVALID_HANDLE_VALUE){

                    CloseHandle(mmHandle);

                }

            }else{

                //char write_chars[] = "hello chars";

                //size_t position = 0;

                //DWORD written = 0;

                //const size_t write_chars_size = sizeof(write_chars);

                //WriteFile(mmHandle,write_chars,write_chars_size,&written,NULL);

                size_t view_size = 1024*256;

                DWORD view_access = FILE_MAP_ALL_ACCESS;

 

                //获得映射视图

                char* mmfm_base_address = (char*)MapViewOfFile(mmfm,view_access,0,0,view_size);

                if(mmfm_base_address == NULL){

                    error_code = GetLastError();

                    if(error_code != SUCCESS){

                        cout<<"error code "<

                    }

                }else{

                    char write_chars[] = "hello chars";

                    const size_t write_chars_size = sizeof(write_chars);

                    //向内存映射视图中写数据

                    CopyMemory((PVOID)mmfm_base_address, write_chars, write_chars_size);

 

                    //memcpy(mmfm_base_address,write_chars,write_chars_size);

                    

                    size_t position = 0;

                    char read_chars[write_chars_size];

 

                    //读数据

                    memcpy(read_chars,mmfm_base_address,write_chars_size);

                    cout<<"read chars "<

                    

                    //卸载映射

                    UnmapViewOfFile(mmfm_base_address);

                    //关闭内存映射文件

                    CloseHandle(mmfm);

                    //关闭文件

                    CloseHandle(mmHandle);

                }

            }

        }

    }

 

    

 

    system("pause");

    exit(0);

    return EXIT_SUCCESS;

}

<!-- 正文结束 -->

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21941142/viewspace-1118187/,如需转载,请注明出处,否则将追究法律责任。

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2009-06-20