📜  C++应用程序中的文件映射

📅  最后修改于: 2021-05-30 14:19:13             🧑  作者: Mango

文件映射是可以为磁盘上的文件创建文件映射对象的概念。此后,不同的进程可以在其虚拟地址空间中创建此文件映射对象的视图。进程可以在其虚拟地址空间中创建文件映射对象的一个或多个视图并对其进行处理。下面是文件映射对象的工作图:

请记住以下要点

  1. 该文件位于运行进程的计算机的磁盘上。
  2. 文件映射对象存在于物理内存中。
  3. 一个以上的进程可以为同一个文件映射对象创建视图。
  4. 文件映射对象可以包含整个文件或部分文件。同样,进程的文件视图可以包含整个文件映射对象或对象的一部分。
  5. 所有副本都是一致的,并且与磁盘上的副本相同。

好处

  1. 当处理诸如数据库文件之类的大文件时,这是一个很大的帮助,因为不需要整个文件都存在于物理内存中。
  2. 一个以上的进程可以将磁盘上的文件用于读取和写入操作。每个进程都可以创建一个新视图,从而取消当前文件视图的映射。

创建文件映射对象和文件视图的步骤

步骤1:创建或打开代表磁盘上文件的文件对象。在这里,我们创建了一个新的文件对象,其句柄为hFile并命名为“ datafile.txt”

HANDLE CreateFileA(
  LPCSTR                lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);

// Can be used as 

HANDLE hFile = CreateFile(TEXT("datafile.txt"),
GENERIC_READ | GENERIC_WRITE,
0,          
// Open with exclusive access
NULL,
// No security attributes

// Creating a new temp file
CREATE_NEW,


// Delete the file after unmapping the view 
FILE_FLAG_DELETE_ON_CLOSE,   
     
        
NULL);
HANDLE CreateFileA(
  LPCSTR                lpFileName,
  DWORD                 dwDesiredAccess,
  DWORD                 dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD                 dwCreationDisposition,
  DWORD                 dwFlagsAndAttributes,
  HANDLE                hTemplateFile
);

// Can be used as 

HANDLE hFile = CreateFile(TEXT("datafile.txt"),
        GENERIC_READ | GENERIC_WRITE,
        0,          // open with exclusive access
        NULL,       // no security attributes
        CREATE_NEW, // creating a new temp file
        FILE_FLAG_DELETE_ON_CLOSE,         //delete the file after unmapping the view
        NULL);

步骤2:为文件创建一个映射对象,其中包含有关如何访问文件及其大小的信息。因此,在创建完上述文件后,我们将使用其句柄并在物理内存中创建其映射。

HANDLE CreateFileMappingA(
  HANDLE                hFile,
  LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
  DWORD                 flProtect,
  DWORD                 dwMaximumSizeHigh,
  DWORD                 dwMaximumSizeLow,
  LPCSTR                lpName
);

// Can be used as 

HANDLE hFileMapping = ::CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, bufferSize, filename);

步骤3:将全部或部分文件映射对象从物理内存映射到进程的虚拟地址空间。因此,我们在这里创建将由流程使用的映射文件的视图。

LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,
  DWORD  dwDesiredAccess,
  DWORD  dwFileOffsetHigh,
  DWORD  dwFileOffsetLow,
  SIZE_T dwNumberOfBytesToMap
);

// Can be used as
void* p = ::MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, param1, param2);

步骤4:清理

4(A)从进程地址空间取消映射文件映射对象。回溯上述步骤,首先,从进程的地址空间中删除文件视图。

BOOL UnmapViewOfFile(LPCVOID lpBaseAddress
);
// Can be used as
UnmapViewOfFile(p);

4(B)关闭文件映射对象。此步骤从物理内存中删除文件映射。

CloseHandle(hFileMapping);

4(C)关闭文件对象。在这里,关闭磁盘上打开的文件并释放句柄。由于在第一步中我们设置了标志FILE_FLAG_DELETE_ON_CLOSE ,因此在此步骤之后将删除该文件。

CloseHandle(hFile);
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”