Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: (faq)проекция файла  (Прочитано 12051 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 31-10-2005 07:54 » 

если я создаю проекцию файла при помощи
Код:

hMapFile=::CreateFileMapping(hFile,0,PAGE_READONLY,0,dwdFileLen,0);
pbyFile=(BYTE*)::MapViewOfFile(hMapFile,FILE_MAP_READ,0,0,0);

, то какие неприятности меня ждут, если я забуду отключить проккцию через

::UnmapViewOfFile()

?
« Последнее редактирование: 30-04-2007 18:09 от Алексей1153++ » Записан

acc15
Гость
« Ответ #1 : 02-11-2005 10:09 » 

To fully close a file mapping object, an application must unmap all mapped views of the file mapping object by calling UnmapViewOfFile, and close the file mapping object handle by calling CloseHandle. The order in which these functions are called does not matter. The call to UnmapViewOfFile is necessary because mapped views of a file mapping object maintain internal open handles to the object, and a file mapping object will not close until all open handles to it are closed.

хотя что подразумевается под словом "забуду"... Если забудешь при выходе, то ничего не будет... если где-то там... то потеряешь память...

подтверждение:
Creating a file mapping object creates the potential for mapping a view of the file but does not map the view. The MapViewOfFile and MapViewOfFileEx functions map a view of a file into a process's address space.

« Последнее редактирование: 20-12-2007 17:49 от Алексей1153++ » Записан
acc15
Гость
« Ответ #2 : 02-11-2005 12:21 » 

глобальных последствий после завершения работы твоей программы не будет никаких...
))) забудь и убедись (попробуй обратиться к этой проекции когда в памяти твоей программы нету)
Записан
Finch
Спокойный
Администратор

il
Online Online
Пол: Мужской
Пролетал мимо


« Ответ #3 : 02-11-2005 12:45 » 

Только два если:
1. Если это именованная проекция
2. Другой процесс также уже открыл проекцию с данным именем.
То проекция останется.
Когда Виндовс завершает процесс, то она сама автоматически закрывает все ресурсы не закрытые во время выполнения процесса. Хороший стиль программирования требует, все ресурсы закрывать если они уже не нужны. Так будет гарантировано, что не будет утечек памяти  и ресурсов во время работы программы.

Цитата
monrus  :

Объясните поподробнее на русском как и где использовать CreateFileMapping, MapViewOfFile, UnmapViewOfFile.

Вот выдержка из книги Рихтера "Windows -для проффесионалов" Глава 17
Цитата
Операции с файлами — это то, что рапо или поздно приходится делать практичес ки во всех программах, и всегда это вызывает массу проблем. Должно ли приложение просто открыть файл, считать и закрыть его, или открыть, считать фрагмент в буфер и перезаписать его в другую часть файла? В Windows многие из этих проблем реша ются очень изящно — с помощью проецируемых в память файлов (memory-mapped files)

Как и виртуальная память, проецируемые файлы позволяют резервировать реги он адресного пространства и передавать ему физическую память. Различие между этими механизмами состоит в том, что в последнем случае физическая память не выделяется из страничного файла, а берется из файла, уже находящегося на диске. Как только файл спроецирован в память, к нему можно обращаться так, будто он цели ком в нее загружен.

Проецируемые файлы применяются для:

загрузки и выполнения EXE- и DLL-файлов Это позволяет существенно эконо мить как на размере страничного файла, так и на времени, необходимом для подготовки приложения к выполнению,
доступа к файлу данных, размещенному на диске Это позволяет обойтись без операций файлового ввода-вывода и буферизации его содержимого,
разделения данных между несколькими процессами, выполняемыми па одной машине (В Windows есть и другие методы для совместного доступа разных процессов к одним данным — но все они так или иначе реализованы на осно ве проецируемых в память файлов.)
<SKIPED>
Вы открываете файл, указывая системе зарезервировать регион виртуального адрес ного пространства. Затем сообщаете, что первый байт файла следует спроецировать на первый байт этого региона, и обращаетесь к региону так, будто он на самом деле содержит файл.
<SKIPED>
Использование проецируемых в память файлов
Для этого нужно выполнить три операции:

1. Создать или открыть объект ядра "файл", идентифицирующий дисковый файл, который Вы хотите использовать как проецируемый в память.

2. Создать объект ядра "проекция файла", чтобы сообщить системе размер фай ла и способ доступа к нему.

3. Указать системе, как спроецировать в адресное пространство Вашего процес са объект «проекция файла» — целиком или частично.

Закончив работу с проецируемым в память файлом, следует выполнить тоже три операции:

1. Сообщить системе об отмене проецирования на адресное пространство про цесса объекта ядра "проекция файла".

2. Закрыть этот объект.

3. Закрыть объект ядра "файл".
<SKIPED>
Этап1: создание или открытие объекта ядра «файл»
Для этого Вы должны применять только функцию CreateFile

HANDLE CreateFile( PCSTR pszFileName, DWORD dwDesiredAccess, DWORD dwShareMode, PSECURITY_AIIRIBUTES psa, DWORD dwCreationDisposition, DWORD dwFlagsAndAttribules, HANDLE hTemplateFile);

------------------------------------------------------------------------------------------------------------------------------------------------
Этап 2: создание объекта ядра «проекция файла»
Вызвав CreateFile, Вы указали операционной системе, где находится физическая па мять для проекции файла на жестком диске в сети, на CD-ROM или в другом месте Теперь сообщите системе, какой обьем физической памяти нужен проекции файла Для этого вызовите функцию CreateFileMapping

HANDLE CreateFileMapping( HANDLE hFile, PSECURITY_ATTRIBUTES psa, DWORD fdwProtect, DWOPD dwMaximumSizeHigh, DWORD dwMaximumSizcLow, PCSTR pszName);
------------------------------------------------------------------------------------------------------------------------------------------------

Этап 3: проецирование файловых данных на адресное пространство процесса
Когда объект "проекция файла"создан, нужно, чтобы система, зарезервировав реги он адресного пространства под данные файла, передала их как физическую память, отображенную на регион. Это делает функция MapViewOfFile

PVOID MapViewOfFile( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap);

------------------------------------------------------------------------------------------------------------------------------------------------------------
Этап 4: отключение файла данных от адресного пространства процесса
Когда необходимость в данных файла (спроецированного на регион адресного про странства процесса) отпадет, освободите регион вызовом:

BOOL UnmapViewOfFile(PVOID pvBaseAddress);
------------------------------------------------------------------------------------------------------------------------------------------------------------
Для повышения производительности при работе с представлением файла систе ма буферизует страницы данных в файле и не обновляет немедленно дисковый об раз файла. При необходимости можно заставить систему записать измененные дан ные (все или частично) в дисковый образ файла, вызвав функцию FlushViewOfFile

BOOL FlushViewOfFile( PVOID pvAddress, SIZE_T dwNuuiberOfBytesToFlush);
------------------------------------------------------------------------------------------------------------------------------------------------------------
Этапы 5 и 6: закрытие объектов «проекция файла» и «файл»
Закончив работу с любым открытым Вами объектом ядра, Вы должны его закрыть, иначе в процессе начнется утечка ресурсов. Конечно, по завершении процесса сис тема автоматически закроет объекты, оставленные открытыми Но, если процесс по работает еще какое-то время, может накопиться слишком много незакрытых описа телей. Поэтому старайтесь придерживаться правил хорошего тона и пишите код так, чтобы открытые объекты всегда закрывались, как только они станут не нужны. Для закрытия объектов «проекция файла» и «файл» дважды вызовите функцию CloseHandle.
------------------------------------------------------------------------------------------------------------------------------------------------------------
Я обещал рассказать, как спроецировать на небольшое адресное просранство файл длиной 16 экзабайтов. Так вот, этого сделать нельзя Вам придется проецировать не весь файл, а сго представление, содержащее лишь некую часть данных Вы начнете с того, что спроецируете представление самого начала файла Закончив обработку дан ных в этом представлении, Вы отключите его и спроецируете представление следую щей части файла — и так до тсх пор, пока нс будет обработан весь файл Конечно, это делает работу с большими файлами, проецируемыми в память, не слишком удоб ной, но утешимся тем, чго длина большинства файлов достаточно мала

Рассмотрим сказанное на примере файла размером 8 Гб Ниже приведен текст подпрограммы, позволяющей в несколько этапов подсчитывать, сколько раз встреча ется нулевой байт в том или ином двоичном файле данных.

__int64 CountOs(void)
{

// начальные границы представлений всегда начинаются no адресам,
// кратным гранулярности выделения памяти
SYSTEM_INFO sinf;
GetSystemInfo(&sinf);

// открываем файл данных
HANOLE hFile = CreateFile( "С:\\HugeFile.Big , GENERIC_READ, FILE_SHARE_READ NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL SCAN, NULL);

// создаем объект проекция файла
HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
DWORD dwFileSizeHigh;

__int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
qwFileSize += (((__int64) dwFileSizeHigh) << 32);

// доступ к описателю объекта файл нам больше не нужен
CloseHandle(hFile);

__int64 qwFileOffset = 0;
qwNumOfOs = 0;

while (qwFileSize > 0)
{

// определяем, сколько байтов надо спроецировать
DWORD dwBytesInBlock = sinf.dwAllocationGranularity;

if (qwFileSize < sinf.dwAllocationGranularity)

dwBytesInBlock = (DWORD)qwFileSize;

PBYTE pbFile = (PBYTE)MapViewOfFile(hFileMapping, FILE_MAP_READ, (DWORD) (qwFileOffset >> 32), // начальный байт (DWORD) (qwFileOffset & 0xFFFFFFFF), // в файле dwBytesInBlock); // число проецируемых байтов

// подсчитываем количество нулевых байтов в этом блоке
for (DWORD dwByte = 0; dwByte < dwBytesInBlock; dwByte++)
{

if (pbFilfe[dwByte] == 0)

qwNumOfOs++;

}


// прекращаем проецирование представления, чтобы в адресном пространстве
// не образовалось несколько представлений одного файла

UnmapViewOfFiie(pbFile);

// переходим к следующей группе байтов в файле
qwFileOffset += dwBytesInBlock;
qwFileSize -= dwBytesInBlock;

}

CloseHandle(hFileMapping);

return(qwNumOfOs);

}

Этот алгоритм проецирует представления по 64 Кб (в соответствии с грануляр ностью выделения памяти) или менее Кроме того, функция MapViewOfFile требует, чтобы передаваемое ей смещение в файле тоже было кратно гранулярности выделе ния памяти. Подпрограмма проецирует на адресное пространство сначала одно пред ставление, подсчитывает в нем количество нулей, затем переходит к другому пред ставлению, и все повторяется. Спроецировав и просмотрев все 64-килобайтовые бло ки, подпрограмма закрывает объект «проекция файла».
Это выдержки из главы. Более подробно почитай ее.
« Последнее редактирование: 06-05-2007 10:58 от Алексей1153++ » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines