文件的内存映射小结(二)

用内存映射文件读取大型文件

        通常情况下,用文件读写函数对文件进行处理,如Win32 API的CreateFile()、WriteFile()、ReadFile()等。一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些特 殊应用领域需要几十GB、几百GB的海量存储,用通常的处理方法进行文件处理显然是行不通的。目前,对于这种大文件的操作一般是以内存映射的方式来加以处 理的。下面以实例说明如何使用内存映射来处理文件。

(1)创建MemFile应用程序的步骤

在Visual C++的MFC下编写这个程序的步骤如下所述。

① 用MFC的AppWizard(exe)创建新项目MemFile

取Project name 为MemFile,单击“确定”按钮后进入创建应用程序类型,选择Dialog based类型并单击Finish按钮。

② CMemFileDlg类文件头

用ClassWizard添加成员变量m_strText以显示一个文件内容,增加一个成员函数LoadFile()以实现用内存映射处理文件的操作。

// MemFileDlg.h: 头文件

//

#if !defined(AFX_MEMFILEDLG_H__INCLUDED_)

#define AFX_MEMFILEDLG_H__INCLUDED_

//

// CMemFileDlg dialog

class CMemFileDlg : public CDialog

{

// Construction

public:

    CMemFileDlg(CWnd* pParent = NULL);  // standard constructor

    ~CMemFileDlg();

// Dialog Data

    //{{AFX_DATA(CMemFileDlg)

    enum { IDD = IDD_MEMFILE_DIALOG };

    CString m_strText;

    //}}AFX_DATA

    // ClassWizard generated virtual function overrides

    //{{AFX_VIRTUAL(CMemFileDlg)

    protected:

    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

    //}}AFX_VIRTUAL

// Implementation

protected:

    HICON m_hIcon;

    BOOL LoadFile(CString strFileName);

    // Generated message map functions

    //{{AFX_MSG(CMemFileDlg)

    virtual BOOL OnInitDialog();

    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()

};

#endif // !defined(AFX_MEMFILEDLG_H__INCLUDED_)

③ 编辑CMemFileDlg::OnInitDialog()

增加LoadFile()函数的调用,再增加UpdateData()函数以便使来自映射文件中的内容得到显示。文件test_memfile.txt为事先准备好的,其内容任意给定。

BOOL CMemFileDlg::OnInitDialog()

{

    CDialog::OnInitDialog();

    // Set the icon for this dialog.  The framework does this automatically

    // when the application's main window is not a dialog

    SetIcon(m_hIcon, TRUE);         // Set big icon

    SetIcon(m_hIcon, FALSE);        // Set small icon

    LoadFile("c://test_memfile.txt");

    UpdateData(FALSE);

    return TRUE;  // return TRUE  unless you set the focus to a control

}

④ 增加CMemFileDlg::LoadFile()函数

首 先用CreateFile()来创建一个读文件的句柄,如果创建失败,函数返回FALSE。接着用CreateFileMapping()创建一个文件映 射对象。同样,如果创建失败,函数返回FALSE。然后用MapViewOfFile()获得文件第一个字节的指针。通过该指针可以得到文件中的全部内 容。最后使用CloseHandle()关闭文件对象和文件映射对象,并且使用UnmapViewOfFile()来释放文件数据映射。

BOOL CMemFileDlg::LoadFile(CString strFileName)

{

    HANDLE hFile, hMapping;

    void *basepointer;

    // Create file object.

    if ((hFile = CreateFile(strFileName, GENERIC_READ,

        FILE_SHARE_READ, 0, OPEN_EXISTING,

        FILE_FLAG_SEQUENTIAL_SCAN, 0))== INVALID_HANDLE_VALUE)

    {

        AfxMessageBox("Could not open file.");

        return FALSE;

    }

    // Creates a named file mapping object.

   if (!(hMapping = CreateFileMapping(hFile,0,PAGE_READONLY|SEC_COMMIT, 0,0,0)))

    {

        AfxMessageBox("Mapping failed.");

        CloseHandle(hFile);

        return FALSE;

    }

    // Map view of file into baseointer.

    if (!(basepointer = MapViewOfFile(hMapping, FILE_MAP_READ,0,0,0)))

    {

        AfxMessageBox("View failed.");

        CloseHandle(hMapping);

        CloseHandle(hFile);

        return FALSE;

    }

    // Close file mapping object.

    CloseHandle(hMapping);

 

    // Close file object.

    CloseHandle(hFile);

    // Get the context of the file.

    m_strText=(LPSTR)basepointer;

    // Unmap view of file.

    UnmapViewOfFile(basepointer);

    return TRUE;

}

(2)用内存映射文件处理文件的实验

首先用notepad 创建一个文件,其文件名为test_memfile.txt,文件的内容设为“北京是中国的首都”,并把这个文件存放在C:/目录下。运行应用程序MemFile.exe后,则在其窗口中显示“北京是中国的首都”这样的字符串,如图1.3所示。

用内存映射文件处理文件的MemFile应用程序

从上面的实例可以看出,用内存映射文件处理文件时不需要用文件数据的读取函数,如ReadFile()等,这给文件的处理,特别是大文件的处理,带来极大的方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值