..::Pam∞¥ov∞ mapovanΘ soubory (PMS)::..

Pou₧φvajφ se k prßci se soubory jako by to byla Φßst pam∞ti. Nap°φklad, kdy₧ mßme data ulo₧ena v poli a b∞hem programu s nimi chceme pracovat. Normßln∞ je nejd°φve t°eba naΦφst data do pam∞ti, pracovat s nimi a nakonec je op∞t ulo₧it. Nejen₧e to dlouho trvß, ale program mß tΘ₧ velkΘ nßroky na pam∞¥. To lze odstranit pou₧itφm PMS. Vytvo°φme, nebo otev°eme PMS, tφm zφskßme ukazatel na zaΦßtek dat a m∙₧eme s nimi pracovat. Po skonΦenφ soubor uzav°eme. Odpadß Φtenφ a zßpis dat na zaΦßtku a na konci a uÜet°φ se pam∞¥.

Postup:

1. Vytvo°it (otev°φt) soubor pomocφ funkce CreateFile(....)
    Parametry:
        1) ╪et∞zec se jmΘnem souboru
        2) Zp∙sob p°φstupu.
            DoporuΦuji pou₧φt kombinaci: GENERIC_READ | GENERIC_WRITE. Tj. pro Φtenφ i zßpis.
        3) Zp∙sob sdφlenφ, pokud soubor chce pou₧φt vφce aplikacφ.
            N∞kterΘ mo₧nosti: FILE_SHARE_READ, FILE_SHARE_WRITE nebo 0.
        4) NULL
        5) Za jak²ch podmφnek otev°φt. DoporuΦuji OPEN_ALWAYS
        6) Atributy souboru. DoporuΦuji FILE_ATTRIBUTE_NORMAL nebo pro doΦasn² sobor (tj. p°i zav°enφ se sma₧e) FILE_FLAG_DELETE_ON_CLOSE|FILE_ATTRIBUTE_TEMPORARY.
        7) NULL

2. Vytvo°it objekt mapovßnφ souboru pomocφ funkce CreateFileMapping(...)
    Parametry:
        1) Handle vrßcenΘ funkcφ CreateFile(...)
        2) NULL
        3) Zp∙sob p°φstupu. DoporuΦuji PAGE_READWRITE.
        4) Minimßlnφ velikost souboru ? DoporuΦuji 0.
        5) Maximßlnφ velikost souboru. Velikost souboru bude nastavena na tuto hodnotu (v bytech).
        6) JmΘno objektu (libovoln² °et∞zec nebo NULL). Pokud tento parametr nebude NULL a bude ve dvou programech stejn² budou programy pracovat se stejn²m souborem (prvnφm otev°en²m).

3. Vytvo°it pohled pomocφ funkce MapViewOfFile(....). Tato funkce zßrove≥ vrßtφ pointer na void, kter² po p°etypovßnφ m∙₧e b²t pou₧it k prßci s daty souboru.
    Parametry:
        1) Hodnota vrßcenß funkcφ CreateFileMapping(...)
        2) Zp∙sob p°φstupu. DoporuΦuji: FILE_MAP_READ|FILE_MAP_WRITE
        3) 0
        4) 0
        5) 0

4. Prßce s daty

5. Uzav°enφ
    UnmapViewOfFile((void*) Nßvratovß hodnota z kroku 3)
    CloseHandle(Nßvratovß hodnota z kroku 2)
    CloseHandle(Nßvratovß hodnota z kroku 1)

Zdrojov² k≤d t°φdy zapouzd°ujφcφ PMS

MyMemMapFile.h

class MyMemMapFile

{

public:

MyMemMapFile();

~MyMemMapFile();

BOOL Open(DWORD size,LPCTSTR file = NULL);

Close();

Resize(DWORD newsize);

void* GetDataPtr();

DWORD GetSize();

protected:

HANDLE hFile,hFileMapping;

void* data,*data_ret;

CString filename;

DWORD velikost;

};

MyMemMapFile.cpp

#include "stdafx.h"

#include "mymemmapfile.h"

MyMemMapFile::MyMemMapFile()

{

hFile = NULL;

hFileMapping = NULL;

data = NULL;

}

MyMemMapFile::~MyMemMapFile()

{

Close();

}

BOOL MyMemMapFile::Open(DWORD size,LPCTSTR file)

{

DWORD flag = FILE_ATTRIBUTE_NORMAL;

velikost = size;

filename = file;

if (file==NULL)

{

char buf[MAX_PATH];

if (GetTempPath(MAX_PATH,buf)==0) return FALSE;

if (GetTempFileName(buf,"mmf",0,buf)==0) return FALSE;

file = buf;

flag = FILE_FLAG_DELETE_ON_CLOSE|FILE_ATTRIBUTE_TEMPORARY;

}

hFile = CreateFile(file,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_ALWAYS,flag,NULL);

if (!hFile)

{

return FALSE;

}

if (size==0)

{

size = GetFileSize(hFile,NULL);

velikost = size;

}

hFileMapping = CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,size,NULL);

if (!hFileMapping)

{

Close();

return FALSE;

}

data = MapViewOfFile(hFileMapping,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);

if (data == NULL)

{

Close();

return FALSE;

}

return TRUE;

}

MyMemMapFile::Close()

{

if (data!=NULL)

{

UnmapViewOfFile(data);

data = NULL;

}

if (hFileMapping!=NULL)

{

CloseHandle(hFileMapping);

hFileMapping = NULL;

}

if (hFile!=NULL)

{

CloseHandle(hFile);

hFile = NULL;

}

}

void* MyMemMapFile::GetDataPtr()

{

return data;

}

MyMemMapFile::Resize(DWORD newsize)

{

MyMemMapFile tmp;

tmp.Open(velikost);

DWORD min;

if (newsize>velikost) min = velikost;

else min = newsize;

char* c = (char*) tmp.GetDataPtr();

char* old = (char*) data;

memcpy(c,old,min);

Close();

Open(newsize,filename);

old = (char*) data;

memcpy(old,c,min);

tmp.Close();

}

DWORD MyMemMapFile::GetSize()

{

return velikost;

}