Я построил этот класс из примера MSDN здесь , и он работает нормально, пока не попытается собрать данные с позиции в середине файла.Неважно, насколько большой я создаю файл, будь то 1 МБ или 512 МБ, все, что больше 1/2, приводит к сбою отображения представления с ошибкой (5), доступ запрещен.
-Предназначен для базы данных, поэтому он состоит из 128-байтовых блоков
-Компилятор использует кодовые блоки с использованием c ++ 11
-Система Win10 64bit
Пример, воссоздающий ошибку:
//Create the map object.
c_NT3_MMap tmp_Map;
//The array to hold the data retrieved.
char tmp_Data[128];
//Open the file "example.dat" with a size of 1MB.
//Predicted max 128 byte chunks = ((1 * (1024 * 1024)) / 128) = 8192
tmp_Map.open_File("example.dat", 1);
//Getting the chunk 4096 which is 1/2 of the computed max works fine.
tmp_Map.get_Chunk(4096, tmp_Data);
//This does not, throws an error code 5 and the map view == NULL.
tmp_Map.get_Chunk(4097, tmp_Data);
Класс для управления отображенным в память объектом:
class c_NT3_MMap
{
private:
//Size of the memory chunk.
const int CONST_BUFFER_SIZE = 128;
//The temporary character array to hold the current node.
char Data[128];
//The file to open.
HANDLE Data_File;
//Handle to the mapped file
HANDLE MMap_File_Mapping;
//Handle to the mapped file view
HANDLE MMap_View;
//System information. Used to get the system granularity.
SYSTEM_INFO system_Info;
DWORD system_Granulation;
//Get the nearest multiple of system grains to the starting offset. Where to start the mapping.
DWORD MMap_Starting_Offset;
//The size of the file mapping view.
//MMap_View_Size = (MMap_Starting_Offset % system_Granulation) + BUFFSIZE
DWORD MMap_View_Size;
//The size of the file mapping object.
DWORD MMap_File_Map_Size;
//The current position of the data pointer in the file.
unsigned long long int MMap_Current_Position;
//The current filename opened
string File_Name;
public:
string file_Name;
void * MMap_Current_Position_Data;
c_NT3_MMap()
{
Data_File = NULL;
MMap_Current_Position = 0;
MMap_File_Map_Size = 0;
MMap_File_Mapping = NULL;
MMap_Starting_Offset = 0;
MMap_View = NULL;
MMap_View_Size = 0;
File_Name = "NOFILE";
}
void get_System_Granulation()
{
// Get the system allocation granularity.
GetSystemInfo(&system_Info);
system_Granulation = system_Info.dwAllocationGranularity;
}
//p_Map_Size is MB
void calculate_Mapping_Parameters(unsigned long long int p_Map_Size = 512)
{
cout << "\n p_Map_Size->" << p_Map_Size;
//Get the system granulation.
get_System_Granulation();
cout << "\n system_Granulation->" << system_Granulation;
//Get the MMap_Starting_Offset for where to start the mapping in the file grains.
MMap_Starting_Offset = 0;//(p_File_Map_Start / system_Granulation) * system_Granulation;
cout << "\n MMap_Starting_Offset->" << MMap_Starting_Offset;
//Calculate the size of the mapping view.
MMap_View_Size = CONST_BUFFER_SIZE;//(p_File_Map_Start % system_Granulation) + CONST_BUFFER_SIZE;
cout << "\n MMap_View_Size->" << MMap_View_Size;
//Figure size of the file mapping object.
MMap_File_Map_Size = (p_Map_Size * (1024 * 1024)) + CONST_BUFFER_SIZE;
cout << "\n MMap_File_Map_Size->" << MMap_File_Map_Size;
//Find the current position of the data pointer to use when referencing file contents.
MMap_Current_Position = MMap_Starting_Offset;
cout << "\n MMap_Current_Position->" << MMap_Current_Position;
}
//Maps the files, does not create the view.
int create_Mapping()
{
MMap_File_Mapping = CreateFileMapping(Data_File, // current file handle
NULL, // default security
PAGE_READWRITE, // read/write permission
0, // size of mapping object, high
MMap_File_Map_Size, // size of mapping object, low
NULL);
if (MMap_File_Mapping == NULL)
{
cout << "\n MMap_File_Mapping == NULL LastError():" << GetLastError();
return 2;
}
return 1;
}
void calculate_View_Parameters(unsigned long long int p_Position)
{
//Get the MMap_Starting_Offset for where to start the mapping in the file grains.
MMap_Starting_Offset = (p_Position / system_Granulation) * system_Granulation;
cout << "\n MMap_Starting_Offset->" << MMap_Starting_Offset;
//Calculate the size of the mapping view.
MMap_View_Size = (p_Position - ((unsigned long long int) (p_Position / system_Granulation))) + CONST_BUFFER_SIZE;
cout << "\n MMap_View_Size->" << MMap_View_Size;
MMap_Current_Position = p_Position;
cout << "\n MMap_Current_Position->" << MMap_Current_Position;
}
//Creates a view at the given offset.
int create_Mapping_View(unsigned long long int p_Position = 0)
{
calculate_View_Parameters(p_Position);
//Do this in case a view is already mapped.
if (MMap_View != NULL)
{
UnmapViewOfFile(MMap_View);
MMap_View = NULL;
}
MMap_View = MapViewOfFile(MMap_File_Mapping, // handle to
// mapping object
FILE_MAP_ALL_ACCESS, // read/write
0, // high-order 32
// bits of file
// offset
MMap_Starting_Offset, // low-order 32
// bits of file
// offset
MMap_View_Size); // number of bytes
// to map
if (MMap_View == NULL)
{
cout << "\n MMap_View == NULL LastError():" << GetLastError();
return 3;
}
MMap_Current_Position_Data = ((char*) MMap_View + MMap_Current_Position);
return 1;
}
//The p_File_Map_Start is the offset to use in the beginning.
//There will be a function for moving the view.
int open_File(string p_File_Name, unsigned long long int p_Map_Size_MB = 512)
{
Data_File = NULL;
File_Name = p_File_Name;
cout << "\n Opening " << p_File_Name;
calculate_Mapping_Parameters(p_Map_Size_MB);
Data_File = CreateFile(p_File_Name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
//Map the file
create_Mapping();
//Create the view.
create_Mapping_View(0);
//Determine if the mapping was a success.
if (MMap_Current_Position_Data == NULL){ return 0; }
return 1;
}
void close()
{
UnmapViewOfFile(MMap_View);
CloseHandle(MMap_File_Mapping);
CloseHandle(Data_File);
}
void save_Data()
{
FlushViewOfFile(MMap_Current_Position_Data, 128);
}
//Gets the current datas.
void get_Data(char * p_Data)
{
if (MMap_View == NULL)
{
cout << "\n MMap_View == NULL LastError():" << GetLastError();
return;
}
for (int cou_Index=0;cou_Index<128;cou_Index++)
{
p_Data[cou_Index] = ((char*)MMap_Current_Position_Data)[cou_Index];
}
}
//Gets a 128 byte chunk.
void get_Chunk(unsigned long long int p_Position, char * p_Data)
{
//Multiply by 128 to get the chunk position, not byte position.
create_Mapping_View(p_Position * 128);
get_Data(p_Data);
}
};
Краткий список некоторых ответов, которые я нашел, но неотноситесь к моей проблеме.
есть ли какое-либо ограничение для использования mapviewoffile Это он пытался отобразить весь файл и ему не хватило памяти
c-createfilemapping-error-5-access-denied-всегда Я не получаю сообщение об ошибке каждый раз, только при доступе ко второй половине блока.
mapviewoffile-return-error-5-error-access-denied Его проблема, похоже, немного другая.Он пытается установить связь между 32-разрядным процессом и 64-разрядным процессом, и его ошибка возникает, когда 32-разрядный процесс создает сопоставление.Я пытаюсь работать с одним файлом с помощью одного процесса.
Глядя на другие ответы, кажется, что у меня где-то неправильные размеры, но из-за жизни я не могу понять, где.