Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проецирование файлов на память 
:(
    Опции темы
chipset
Дата 31.1.2005, 05:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 164



 Практические примеры - на WinAPI, и на MFC

Теория:
Файл, спроецированный на память - это механизм Win32 API, позволяющий любой открытый файл рассматривать как блок пямяти с произвольным доступом (все записи и чтения байта по адресу, лежащему в пределах такого блока, приводят к изменению соотв. байта в файле). Это может быть очень удобно, когда необходимо работать с файлами очень большого объема: вместо того, чтобы читать всё содержимое файла в память (или искать нужный фрагмент функцией Seek), можно спроецировать файл на память и сразу прочитать или модифицировать нужный фрагмент памяти. Windows подгружает спроецированный файл постранично, по мере обращения к тем или иным адресам памяти; всё делается автоматически, на уровне механизма виртуальной памяти Win32, что избавляет от необходимости вручную следить за подгрузкой из файла или записью в файл ненужных участков памяти.

Пример на MFC:
Чтобы упростить себе жизнь, создадим простой класс на основе CFile (класс-предок будет заниматься открытием и закрытием файлов; нам же останется только реализовать в нашем классе пару функций для проецирования файла):
Код
 class CMemoryMappedFile: public CFile
{
protected:
     HANDLE m_hMapping;     // хэндл объекта "проекция файла"
     void *m_bufMapping;      // стартовый адрес проекции

public:   // набор конструкторов
     CMemoryMappedFile() {m_hMapping=NULL;}
     CMemoryMappedFile(char *strFileName, UINT openFlags): CFile(strFileName, openFlags) {m_hMapping=NULL;}
     ~CMemoryMappedFile() {if(m_hMapping) ReleaseMemoryMapping();}

public:  // пара функций "спроецировать" / "освободить проекцию"
     void *GetMemoryMapping(bool bReadOnly=false);
     void ReleaseMemoryMapping();
};



// функция проецирует файл на память (файл должен быть уже открыт)
// и возвращает стартовый адрес блока памяти
void *CMemoryMappedFile::[b]GetMemoryMapping(bool bReadOnly)[/b]
{
     if(!m_hFile || m_hMapping) return NULL;
     m_hMapping = CreateFileMapping((void*)m_hFile, 0, bReadOnly?PAGE_READONLY:PAGE_READWRITE, 0, 0, 0);
     if(!m_hMapping) return NULL;
     m_bufMapping = MapViewOfFile(m_hMapping, FILE_MAP_READ|(bReadOnly?0:FILE_MAP_WRITE), 0, 0, 0);
     if(!m_bufMapping) CloseHandle(m_hMapping);
     return m_bufMapping;
}


// освобождение проекции
void CMemoryMappedFile::[b]ReleaseMemoryMapping[/b]()
{
     if(!m_hMapping) return;
     UnmapViewOfFile(m_bufMapping);
     CloseHandle(m_hMapping);
     m_hMapping = NULL;
}

// ===============================================

// пример - создадим текстовый файл на диске С: и запишем
// в него строку текста, затем заменим третий символ на "Z":
void DemoFileMapping()
{
     CMemoryMappedFile file("c:\\1.txt", CFile::modeCreate|CFile::modeReadWrite);
     char *str = "ABCDEFG";
     file.Write(str, strlen(str));

     char *buf = (char*)file.GetMemoryMapping();
     buf[2] = 'Z';
     file.ReleaseMemoryMapping();
}



Пример на "чистом" WinAPI:
Код
// пример - создадим текстовый файл на диске С: и запишем
// в него строку текста, затем заменим третий символ на "Z":
void  DemoFileMapping()
{
     HANDLE hFile = CreateFile ( "c:\\1.txt", GENERIC_READ | GENERIC_WRITE,
          FILE_SHARE_READ|FILE_SHARE_WRITE,
          NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
     
     DWORD d; 
     char *str = "ABCDEFG";
     WriteFile(hFile, str, strlen(str), &d, 0);
    
     HANDLE mapping = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, 0, 0);
     if(mapping)
     {
          char *buf = (char *)MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
          if(buf)
          {
               buf[2] = 'Z';
               UnmapViewOfFile(buf);
          }
          CloseHandle(mapping);
     }
     CloseHandle(hFile);
}
 


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0610 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.