Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up
Отображением файла в память мы с вами пользовались в заметках об OpenGL, посвященных работе с моделями и текстурами, но не рассматривали подробно, как именно это работает. И хотя я почти уверен, что многие читатели этого блога уже знакомы с отображением файлов в память, я все же посчитал необходимом написать соответствующие заметки для тех читателей, кому данный механизм не знаком. Сегодня мы рассмотрим, как все это работает под Windows.
Заведем такую структуру, хранящую хэндл файла, хэндл отображения, размер файла, а также указатель на участок памяти с отображением:
#include <windows.h>
struct FileMapping {
HANDLE hFile;
HANDLE hMapping;
size_t fsize;
unsigned char* dataPtr;
};
Рассмотрим чтение из файла с использованием отображения.
Открываем файл:
HANDLE hFile = CreateFile(fname, GENERIC_READ, 0, nullptr,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, nullptr);
if(hFile == INVALID_HANDLE_VALUE) {
std::cerr << «fileMappingCreate — CreateFile failed, fname = «
<< fname << std::endl;
return nullptr;
}
С процедурой CreateFile мы уже знакомы по заметке Учимся работать с файлами через Windows API, поэтому двигаемся дальше.
Получаем размер файла:
DWORD dwFileSize = GetFileSize(hFile, nullptr);
if(dwFileSize == INVALID_FILE_SIZE) {
std::cerr << «fileMappingCreate — GetFileSize failed, fname = «
<< fname << std::endl;
CloseHandle(hFile);
return nullptr;
}
Вторым аргументом процедура GetFileSize получает указатель на DWORD для записи старшей части размера файла. Передав в качестве этого аргумента nullptr, мы ограничили размер файла, который может вернутся. Если размер файла будет 4 Гб или больше, процедура вернет ошибку.
Создаем отображение:
HANDLE hMapping = CreateFileMapping(hFile, nullptr, PAGE_READONLY,
0, 0, nullptr);
if(hMapping == nullptr) {
std::cerr << «fileMappingCreate — CreateFileMapping failed, fname = «
<< fname << std::endl;
CloseHandle(hFile);
return nullptr;
}
Заметьте, что hMapping проверяется на равенство nullptr. Это не баг — согласно MSDN, в случае ошибки CreateFileMapping действительно возвращает пустой указатель, а не INVALID_HANDLE_VALUE, как можно было бы ожидать. Такая неконсистентность, к сожалению, встречается время от времени в WinAPI. Мы уже встречались с этой проблемой, изучая работу с реестром.
Наконец, получаем указатель на участок памяти с отображением, используя процедуру MapViewOfFile:
unsigned char* dataPtr = (unsigned char*)MapViewOfFile(hMapping,
FILE_MAP_READ,
0,
0,
dwFileSize);
if(dataPtr == nullptr) {
std::cerr << «fileMappingCreate — MapViewOfFile failed, fname = «
<< fname << std::endl;
CloseHandle(hMapping);
CloseHandle(hFile);
return nullptr;
}
Затем заполняем структуру FileMapping и возвращаем указатель на нее в качестве результата:
FileMapping* mapping = (FileMapping*)malloc(sizeof(FileMapping));
if(mapping == nullptr) {
std::cerr << «fileMappingCreate — malloc failed, fname = «
<< fname << std::endl;
UnmapViewOfFile(dataPtr);
CloseHandle(hMapping);
CloseHandle(hFile);
return nullptr;
}
mapping—>hFile = hFile;
mapping—>hMapping = hMapping;
mapping—>dataPtr = dataPtr;
mapping—>fsize = (size_t)dwFileSize;
return mapping;
Теперь читая mapping->fsize байт памяти по адресу mapping->dataPtr можно получить содержимое файла.
Когда отображение становится ненужным, не забываем его закрыть:
UnmapViewOfFile(mapping—>dataPtr);
CloseHandle(mapping—>hMapping);
CloseHandle(mapping—>hFile);
free(mapping);
Как видите, все предельно просто. Исходники к этой заметке вы найдете здесь.
В качестве домашнего задания можете попробовать модифицировать код так, чтобы через отображение файл можно было не только читать, но и писать в него.
Задание со звездочкой для желающих — ответьте на следующий вопрос. Можно ли, работая с отображением файла в память, менять его размер, например, делать append или обрезать файл посередине, и если можно, то как? Если честно, я сам так с лету не готов ответить на этот вопрос, потому что такой задачи передо мной не вставало. Так что, с нетерпением жду ваших вариантов ответа в комментариях!
Дополнение: Пример отображения файла в память под Linux и MacOS
Метки: C/C++, WinAPI.
Posting Permissions
Forum Rules |
|
NETWORK ADMINISTRATIONSWindows server
Alice AUSTIN
How to create a file in memory in Windows Server? Helpful? Please support me on Patreon: https://www.patreon.com/roelvandepaar With thanks & praise to God …
source
windows server
- DevOps & SysAdmins: SSL for OpenLDAP on Centos 7 not working (2 Solutions!!)
- Division2 DZ みんなのうた [ディビジョン2 PVP/PVE]
Alice AUSTIN
Alice AUSTIN is studying Cisco Systems Engineering. He has passion with both hardware and software and writes articles and reviews for many IT websites.
You May Also Like
Servidor web com Ubuntu #1 – Instalação e otimização do SO
Veloren – Exploring this Free RPG! – Open Source & Linux (Q&A) – (Minecraft / Cube World)
Microsoft Server Down, Airtel Copying Jio Again, FBI Unlock Samsung Phone, Fake IRCTC Refund Website
Alice AUSTIN
Leave a Reply
Your email address will not be published. Required fields are marked *
Comment *
Name *
Email *
Website
Save my name, email, and website in this browser for the next time I comment.
