对Windows下的File Mapping一个简单的封装

头文件:

#ifndef __SharedMemory_H__
#define __SharedMemory_H__


class SharedMemory
{
public:
    /// 访问模式
    enum AccessMode
    {
        AM_READ = 0,    ///< 读
        AM_WRITE        ///< 写
    };

public:
    SharedMemory(const std::string& name, std::size_t size, AccessMode mode, const void* addrHint = 0, bool server = true);
    SharedMemory(const std::string& fileName, SharedMemory::AccessMode mode, const void* addrHint = 0);
    ~SharedMemory();

public:
    /// 共享内存的起始指针
    char* begin() const;

    /// 共享内存的尾部指针
    char* end() const;

    /// 共享内存的名字
    std::string name() const;

protected:
    void map();

    void unmap();

    void close();

private:
    SharedMemory();
    SharedMemory(const SharedMemory&);
    SharedMemory& operator = (const SharedMemory&);

    std::string    m_name;
    HANDLE        m_memHandle;
    HANDLE        m_fileHandle;
    DWORD        m_size;
    DWORD        m_mode;
    char*        m_address;
};


inline char* SharedMemory::begin() const
{
    return m_address;
}

inline char* SharedMemory::end() const
{
    return m_address + m_size;
}

inline std::string SharedMemory::name() const

    return m_name; 
}


#endif

实现文件


#include "stdafx.h"
#include "SharedMemory.h"

SharedMemory::SharedMemory(const std::string& name, 
                           std::size_t size, 
                           SharedMemory::AccessMode mode, 
                           const void* addrHint, 
                           bool)
                           : m_name(name)
                           , m_memHandle(INVALID_HANDLE_VALUE)
                           , m_fileHandle(INVALID_HANDLE_VALUE)
                           , m_size(static_cast<DWORD>(size))
                           , m_mode(PAGE_READONLY)
                           , m_address(0)
{
    if (mode == SharedMemory::AM_WRITE)
    {
        m_mode = PAGE_READWRITE;
    }

    m_memHandle = ::CreateFileMapping(INVALID_HANDLE_VALUE,
        NULL, 
        m_mode, 
        0, 
        m_size, 
        m_name.c_str());

    if (!m_memHandle)
    {
        //throw SystemException("Cannot create shared memory object", m_name);
    }

    map();
}

SharedMemory::SharedMemory( const std::string& fileName, AccessMode mode, const void* addrHint )
: m_name(fileName)
, m_memHandle(INVALID_HANDLE_VALUE)
, m_fileHandle(INVALID_HANDLE_VALUE)
, m_size(0)
, m_mode(PAGE_READONLY)
, m_address(0)
{
    DWORD shareMode = FILE_SHARE_READ;
    DWORD fileMode  = GENERIC_READ;

    if (mode == SharedMemory::AM_WRITE)
    {
        m_mode = PAGE_READWRITE;
        fileMode |= GENERIC_WRITE;
    }

    m_fileHandle = ::CreateFile(m_name.c_str(), 
        fileMode, 
        shareMode,
        NULL,
        OPEN_EXISTING, 
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (m_fileHandle == INVALID_HANDLE_VALUE)
    {
        //throw OpenFileException("Cannot open memory mapped file", m_name);
        return;
    }

    m_size = ::GetFileSize(m_fileHandle, NULL);

    m_memHandle = ::CreateFileMapping(m_fileHandle, NULL, m_mode, 0, 0, NULL);
    if (!m_memHandle)
    {
        ::CloseHandle(m_fileHandle);
        m_fileHandle = INVALID_HANDLE_VALUE;
        //throw SystemException("Cannot map file into shared memory", m_name);
    }
    map();
}

SharedMemory::~SharedMemory()
{
    unmap();
    close();
}

void SharedMemory::map()
{
    DWORD access = FILE_MAP_READ;
    if (m_mode == PAGE_READWRITE)
    {
        access = FILE_MAP_WRITE;
    }
    LPVOID addr = ::MapViewOfFile(m_memHandle, access, 0, 0, m_size);
    if (!addr)
    {
        //throw SystemException("Cannot map shared memory object", m_name);
    }

    m_address = static_cast<char*>(addr);
}

void SharedMemory::unmap()
{
    if (m_address)
    {
        ::UnmapViewOfFile(m_address);
        m_address = 0;
        return;
    }
}

void SharedMemory::close()
{
    if (m_memHandle != INVALID_HANDLE_VALUE)
    {
        ::CloseHandle(m_memHandle);
        m_memHandle = INVALID_HANDLE_VALUE;
    }

    if (m_fileHandle != INVALID_HANDLE_VALUE)
    {
        ::CloseHandle(m_fileHandle);
        m_fileHandle = INVALID_HANDLE_VALUE;
    }
}

示例代码

    LPCTSTR szFilePath = TEXT("E:\xxx.zip");
    SharedMemory sharedMemory(szFilePath, SharedMemory::AM_READ);
    char* pFileBegin = sharedMemory.begin();

时间: 2024-09-20 00:51:03

对Windows下的File Mapping一个简单的封装的相关文章

Windows下Java File对象创建文件夹时的一个&quot;坑&quot;

import java.io.File; import java.io.IOException; public class DirCreate { public static void main(String[] args) throws IOException { // TODO Auto-generated method stub String dirStr="D:"; File dir=new File(dirStr); System.out.println("====

在Windows下使用Notepad++和xdebug调试php脚本

介绍 Notepad++ 是开放源代码的可替代记事本的编辑器.它运行于 MS Windows 环境,支持多种编程语言.可以浏览 http://notepad-plus.sourceforge.net/ 了解更多相关信息. Xdebug 是 php 的一个扩展,它提供了对 php 脚本进行除错.追踪.检查的各种功能.可以浏览 http://xdebug.org 了解更多相关信息. 下载 Notepad++ 下载地址:http://nchc.dl.sourceforge.net/sourceforg

在Windows下利用Squid开设代理服务器_服务器其它

在"突破公司网络封锁,畅游无限网络"一文提到解决方案中,是利用ccproxy来建立proxy server.ccproxy是图形界面程序,使用比较简单,但是存在着两个问题:首先ccproxy不是免费软件,未注册版本只能提供3个连接:另外一个就是从性能还是稳定性上都不是特别让人满意. 后来发现自己的确孤陋寡闻,Unix/Linux下大名鼎鼎的开源免费代理软件Squid(www.squid-cache.org)是有Windows的Native版本SquidNT.既然如此,Squid一出,谁

[20161006]windows下bbed使用注意.txt

[20161006]windows下bbed使用注意.txt --我已经多次提到windows下 的bbed 存在一个偏移看10g以上的数据文件,主要问题在于windows的bbed来自9i,以后不在出现. --而这个版本无法识别10g以上的数据文件的第1块OS块,导致出现偏差: http://blog.itpub.net/267265/viewspace-2109019/ http://blog.itpub.net/267265/viewspace-2116311/ --而实际上更严重的问题是

服务器-项目导出成war包放在linux的weblogic上可以跑,在windows下跑不了

问题描述 项目导出成war包放在linux的weblogic上可以跑,在windows下跑不了 公司的一个老旧项目,在笔记本下win7 tomcat 可以随便跑:在笔记本用weblogic跑不动,当时以为是电脑配置太差了.于是放到了组里的linux上的weblogic跑.挺快的. 现在公司要求放到windows server 2008的服务器上的weblogic,可是和在笔记本上用weblogic同样:登录了之后加载不出页面,过了很久很久显示500超时错误.求各位大神遇到过此问题的告诉下解决方法

在Windows下利用Squid开设代理服务器

unix/linux下大名鼎鼎的开源免费代理软件squid(www.squid-cache.org)是有windows的native版本squidnt.既然如此,squid一出,谁与争锋? squid在windows下的安装配置同样简单,包括一下几步: 1. 下载squid 可以下载源码自己编译,当然更方便的就是直接下载二进制文件了.下载列表在这里:http://www.acmeconsulting.it/squidnt/,或者直接从下面链接: squid-2.6 – squid-2.7 2.安

我的Android进阶之旅------&amp;gt;Android关于Log的一个简单封装

android.util.Log类,可以方便地用于在编码调试过程中打印日志.但是在发布后的产品中,如果有太多的日志打印,则会严重地影响性能.对android.util.Log类做一个简单的封装,当产品要发布的话,将Debug设为false. 代码如下. public class LogUtil { /**正式上线時候设为false*/ private final static boolean debug = true; private final static String TAG = "oyp

Windows下一个简单的日志系统的C代码实现

       问题描述        实现一个简单的基于Windows的日志系统,要求写入日志文件的内容的样式如下:        [时间]+[文件名]+[日志等级]+日志具体内容        如:        [2015.02.2514:35:13.143][WriteLog.c][INFO]This is a test!        其中,"2015.02.25 14:35:13.143"为当前时间(精确到毫秒),"WriteLog.c"为所打印的日志内容

Windows 8 Store Apps学习(64) 后台任务: 开发一个简单的后台任务

介绍 重新想象 Windows 8 Store Apps 之 后台任务 开发一个简单的后台任务 示例 1.通过"Windows 运行时组件"新建一个后台任务 BackgroundTaskLib/Demo.cs /* * 后台任务 * * 注: * 后台任务项目的输出类型需要设置为"Windows 运行时组件",其会生成 .winmd 文件,winmd - Windows Metadata */ using System; using System.Threading