Как отобразить файл в память (CreateFileMapping),чтобы изменения не сохранились в файле?

195
11 марта 2018, 23:22

Отображаю файл в память:

hMapObject = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
lpBase = MapViewOfFile(hMapObject, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0);

Затем мне нужно совершить некоторые операции(модификация) над отображаемой информацией в памяти. При этом я не хочу, чтобы эти изменения перенеслись на файл на диске. Как мне быть? Думаю над тем, чтобы скопировать отображаемую информацию в другую область памяти и там совершать изменения, но пока не понимаю в какую область памяти мне можно скопировать информацию

Answer 1

Насколько я понимаю, в механизме работы отображения файлов на память предусмотрен и Ваш случай. В вызове MapViewOfFile() нужно использовать параметр FILE_MAP_COPY - он будет создавать копии измененных страниц памяти в адресном пространстве Вашего процесса. При этом, само отображение (как объект ядра) можно создавать с атрибутом PAGE_WRITECOPY. Но это не точно :-) . В том смысле, что так сделано в примере в книге: Рихтер Дж. "Windows для профессионалов: создание эффективных Win32-приложений с учетом специфики 64-разрядной версии Windows" / Пер. с англ. — 4-е изд. — Спб.: Питер; М.: Издательство «Русская Редакция»; 2008. — 720 стр.: ил. (стр. 428 о работе с файлами, отображаемыми на память).

Сам же я открывал файл и отображение - только на чтение. Вроде, бы все работает и так (у меня был текстовый файл и с него надо было многократно извлекать данные, и соответственно, я работал с ним как с обычной си-строкой. А чтобы она стала "строкой", в отображении нужно было подменять последний символ на '\0').

В итоге:

hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY|FILE_FLAG_RANDOM_ACCESS, 0);
hMap  = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
mapwnd = MapViewOfFile(hMap, FILE_MAP_COPY, 0, 0, 0); // если нужно отобразить файл целиком
// здесь обрабатываем отображенный файл
UnmapViewOfFile(mapwnd);

Либо как у Рихтера в книге:

HANDLE hFile = CreateFile(pszFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_WRITECOPY, 0, 0, NULL);
PBYTE pbFile = (PBYTE) MapViewOfFile(hFileMapping, FILE_MAP_COPY, 0, 0, 0);
// здесь у Рихтера что-то изменяется в pbFile
UnmapViewOfFile(pbFile);

В комментариях к примеру он пишет, что все измененные данные будут потеряны при закрытии отображения.

Естественно, на каждом этапе нужно обрабатывать возвращаемые ошибки, а после работы - закрывать все дескрипторы. Я эту часть кода опустил.

READ ALSO
Что означает параметр tcpi_rcv_rtt в структуре tcp_info?

Что означает параметр tcpi_rcv_rtt в структуре tcp_info?

В структуре tcp_info описаны вот такие параметры, описывающие RTT:

159
/DEBUG:FASTLINK в visual studio

/DEBUG:FASTLINK в visual studio

При компиляции проекта в visual studio выдаётся следующая ошибка:

187
сжатие ipv6 адреса [требует правки]

сжатие ipv6 адреса [требует правки]

Написать функцию на языке C++, которая преобразует адрес в шестнадцатеричной системе счисления с двоеточием в сжатую формуНапример вот такой...

151
Запросы в retrofit

Запросы в retrofit

Как можно сделать запрос такого типа в Retrofit?

172