Этап 4: отключение файла данных от адресного пространства процесса
Когда необходимость в данных файла (спроецированного на регион адресного про странства процесса) отпадет, освободите регион вызовом:
BOOL UnmapViewOfFile(PVOID pvBaseAddress);
Ее единственный параметр, pvBaseAddress, указывает базовый адрес возвращаемо го системе региона. Он должен совпадать со значением, полученным после вызова MapViewOfFile. Вы обязаны вызывать функцию UnmapViewOfFile. Если Вы не сделаете этoro, регион не освободится до завершения Вашего процесса. И еще: повторный вызов MapVietvOfFile приводит к резервированию нового региона в пределах адрес ного пространства процесса, но ранее выделенные регионы не освобождаются.
Для повышения производительности при работе с представлением файла систе ма буферизует страницы данных в файле и не обновляет немедленно дисковый об раз файла. При необходимости можно заставить систему записать измененные дан ные (все или частично) в дисковый образ файла, вызвав функцию FlushViewOfFile
BOOL FlushViewOfFile( PVOID pvAddress, SIZE_T dwNuuiberOfBytesToFlush);
Ее первый параметр принимает адрес байта, который содержится в границах пред ставления файла, проецируемого в память. Переданный адрес округляется до значе ния, кратного размеру страниц, Второй параметр определяет количество байтов, ко торые надо записать в дисковый образ файла. Если FlusbViewOfFile вызывается в от сутствие измененных данных, она просто возвращает управление.
В случае проецируемых файлов, физическая память которых расположена на се тевом диске, FlushViewOfFile гарантирует, что файловые данные будут перекачаны с рабочей станции. Но она не гарантирует, что сервер, обеспечивающий доступ к это му файлу, запишет данные на удаленный диск, так как он может просто кэшировать их. Для подстраховки при создании объекта «проекция файла» и последующем про ецировании его представления используйте флаг FILE_FLAG_WRITE_THROUGH. При открытии файла с этим флагом функция FlushViewOfFile вернет управление только после сохранения на диске сервера всех файловых данных.
У функции UnmapViewOfFile есть одна особенность. Если первоначально представ ление было спроецировано с флагом FILE_MAP_COPY, любые изменения, внесенные Вами в файловые данные, на самом деле производятся над копией этих данных, хра нящихся в страничном файле. Вызванной в этом случае функции UnmapViewOfFile нечего обновлять в дисковом файле, и она просто инициирует возврат системе стра ниц физической памяти, выделенных из страничного файла. Все изменения в данных на этих страницах теряются.
Поэтому о сохранении измененных данных придется заботиться самостоятель но. Например, для уже спроецированного файла можно создать еще один объект «про
екция файла» с атрибутом PAGE_READWRITE и спроецировать его представление на адресное пространство процесса с флагом FILE_MAP_WRITE. Затем просмотреть пер вое представление, отыскивая страницы с атрибутом PAGE_READWRITE. Найдя стра ницу с таким атрибутом. Вы анализируете ее содержимое и решаете: записывать ее или нет Если обновлять файл не нужно, Вы продолжаете просмотр страниц. А для сохранения страницы с измененными данными достаточно вызвать MoveMemory и скопировать страницу из первого представления файля во второе. Поскольку второе представление создано с атрибутом PAGE_READWRITE, функция MoveMemory обновит содержимое дискового файла. Так что этот метод вполне пригоден для анализа изме нений и сохранения их в файле.
WINDOWS 98
Windows 98 нс поддерживает атрибут защиты «копирование при записи», по этому при просмотре первого представления файла, проецируемого в память, Вы не сможете проверить страницы по флагу PAGE_READWRITE Вам придется разработать свой метод.