Сопоставление файлов в приложениях C++

Опубликовано: 14 Сентября, 2022

Отображение файлов — это концепция, в которой объект карты файлов может быть создан для файла на диске. После этого различные процессы могут создать представление этого объекта сопоставления файлов в своих виртуальных адресных пространствах. Процесс может создать одно или несколько представлений объекта сопоставления файлов в своем виртуальном адресном пространстве и работать с ним. Ниже приведена рабочая схема объекта сопоставления файлов:

Помните о следующих ключевых моментах

  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);

Note:

  1. Close the handles in the same order or else it will give rise to discrepancies.
  2. Close all the open file handles before trying to delete the file.
C++