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

Поиск:

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


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 15.9.2004
Где: Saratov

Репутация: 14
Всего: 24



Очень хотелось бы работать с большими (порядка 1-2 Гб) файлами как с единым массивом байт, не используя файловые операции ввода-вывода C/C++. Подумал, что для таких целей лучше всего воспользоваться проецированием файлов в память, но когда попытался сие реализовать, наткнулся на ряд подводных камней.

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

Примерный код в упрощенном виде:
Код

...
// Открываем объект ядра "файл"
HANDLE hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
// Создаем объект ядра "проекция файла"
HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
// Проецируем в адресное пространство процесса объект "проекция файла"
PBYTE pbFile = (PBYTE) MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
...


Время от времени программа "спотыкается" при вызове MapViewOfFile. pbFile при этом равен NULL, а функция GetLastError возвращает значение 8 ("Недостаточно памяти для обработки команды"). Причем никак не могу проследить логику возникновения данной ситуации - то файл размером ~1,2 Гб проецируется на ура (при этом запущена куча приложений), то файл ~600 Мб не хочет (притом, что практически ничего не запущено). Утечек памяти в программе нет. Все, что открывается - то закрывается, все что выделяется - то освобождается... Если снять галки с "Build with runtime packages" и "Use dymamic RTL", то ситуация улучшается, можно работать с бОльшими по размеру файлами. Если же ничего к программе не цеплять, то опять нехватка памяти.

От чего зависит размер файла, который можно целиком маппировать в память?
Или придется отказаться от проецирования файла целиком, и маппировать его по кускам? (...чего, собственно, очень хотелось бы избежать, в таком случае уж лучше стандартными C++-средствами с файлом работать...)


--------------------
"Разруха не в клозетах, а в головах." © Ф.Ф. Преображенский (М.Булгаков, "Собачье сердце")
PM WWW ICQ   Вверх
Empirik
Дата 16.2.2006, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 156
Регистрация: 28.10.2005
Где: Россия, Пермь

Репутация: нет
Всего: 1



А чем тебе не нравиться fstream (fstream - заголовочный файл)? У него же можно указать размер буфера. Или я не правельно понимаю, чего ты хочешь

Это сообщение отредактировал(а) Empirik - 16.2.2006, 13:34
--------------------
Постоянно удивляюсь человеческой фантазии напридумывают гаджетов
PM MAIL WWW ICQ   Вверх
_hunter
Дата 16.2.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



размер файла, который можно спроецировать должен быть меньше размера свободной памяти иначе будет выполняться копирование с диска на диск ( а оно нам надо? )


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Lotrex
Дата 16.2.2006, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 9.2.2006
Где: Казань

Репутация: 2
Всего: 3



BreakPointMAN, Вы в одном процессе только один файл отображаете, или несколько?
PM MAIL ICQ   Вверх
BreakPointMAN
Дата 16.2.2006, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 15.9.2004
Где: Saratov

Репутация: 14
Всего: 24



Цитата(Empirik @ 16.2.2006, 13:33 Найти цитируемый пост)
А чем тебе не нравиться fstream (fstream - заголовочный файл)? У него же можно указать размер буфера. Или я не правельно понимаю, чего ты хочешь

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

Цитата(Lotrex @ 16.2.2006, 16:41 Найти цитируемый пост)
BreakPointMAN, Вы в одном процессе только один файл отображаете, или несколько?

Несколько, по очереди.


--------------------
"Разруха не в клозетах, а в головах." © Ф.Ф. Преображенский (М.Булгаков, "Собачье сердце")
PM WWW ICQ   Вверх
Lotrex
Дата 16.2.2006, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 9.2.2006
Где: Казань

Репутация: 2
Всего: 3



Цитата

Несколько, по очереди.


То есть у Вас файлы отображаются не одновременно? Сначала один отображаете, с ним работаете, потом все, что с ним связано закрываете/грохаете, опосля беретесь за другой, так? Я спрашиваю, потому что в винде для каждого процесса отводится по 2Гб памяти. Если сумма объемов отображаемых одновременно файлов (в одном процессе) будет превышать это значение, то это может вызвать ту ошибку...

И еще: у Вас последний параметр функции MapViewOfFile (параметр dwNumberOfBytesToMap) равен 0. Вот что про энтот параметр в описании написано:
Цитата

dwNumberOfBytesToMap
[in] The number of bytes of a file mapping to map to the view. If this parameter is 0 (zero), the mapping extends from the specified offset to the end of the section.


От указанного смещения до конца секции, а не файла! Черт его знает, что это секция означает, но мож просто туды вместо 0 размер файла влындить для ясности? smile

Это сообщение отредактировал(а) Lotrex - 16.2.2006, 20:26
PM MAIL ICQ   Вверх
BreakPointMAN
Дата 16.2.2006, 21:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 15.9.2004
Где: Saratov

Репутация: 14
Всего: 24



Цитата(Lotrex @ 16.2.2006, 19:42 Найти цитируемый пост)
То есть у Вас файлы отображаются не одновременно? Сначала один отображаете, с ним работаете, потом все, что с ним связано закрываете/грохаете, опосля беретесь за другой, так?

Именно так.

Цитата(Lotrex @ 16.2.2006, 19:42 Найти цитируемый пост)
Черт его знает, что это секция означает, но мож просто туды вместо 0 размер файла влындить для ясности?

Пробовал...


Цитата(_hunter @ 16.2.2006, 13:41 Найти цитируемый пост)
размер файла, который можно спроецировать должен быть меньше размера свободной памяти иначе будет выполняться копирование с диска на диск ( а оно нам надо? )

ну... пошуршал бы винтом... поюзал бы файл подкачки...


По всей видимости, ошибка возникает, когда нет непрерывного куска памяти достаточного размера в адресном пространстве... от чего может зависеть фрагментация адресного пространства процесса?


--------------------
"Разруха не в клозетах, а в головах." © Ф.Ф. Преображенский (М.Булгаков, "Собачье сердце")
PM WWW ICQ   Вверх
zss
Дата 16.2.2006, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



BreakPointMAN, дядька Рихтер приводил пример обработки больших фалов по частям
PM MAIL ICQ   Вверх
BreakPointMAN
Дата 16.2.2006, 23:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 15.9.2004
Где: Saratov

Репутация: 14
Всего: 24



Цитата(zss @ 16.2.2006, 21:41 Найти цитируемый пост)
BreakPointMAN, дядька Рихтер приводил пример обработки больших фалов по частям

Читал, знаю... smile
Цитата(Рихтер)

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


но... блин... очень не хотелось бы так делать... одно дело 16 экзабайтов, другое - 1-2 гигабайта... если маппировать по частям, то теряется вся прелесть данного подхода и придется усложнять алгоритм... smile


--------------------
"Разруха не в клозетах, а в головах." © Ф.Ф. Преображенский (М.Булгаков, "Собачье сердце")
PM WWW ICQ   Вверх
Lotrex
Дата 17.2.2006, 08:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 9.2.2006
Где: Казань

Репутация: 2
Всего: 3



Цитата(BreakPointMAN @ 16.2.2006, 21:10 Найти цитируемый пост)
По всей видимости, ошибка возникает, когда нет непрерывного куска памяти достаточного размера в адресном пространстве... от чего может зависеть фрагментация адресного пространства процесса?


Хрен его знает... Я даже не знаю, как можно кучу дефрагментировать.... Может, что бы со всей этой дефрагментацией для работы с файлом отдельный процесс (thread)создавать? У него адресное пространство чистенькое будет, не фрагментированное...
PM MAIL ICQ   Вверх
threef
Дата 17.2.2006, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 27.10.2005
Где: Запорожье

Репутация: 9
Всего: 10



Цитата

Хрен его знает... Я даже не знаю, как можно кучу дефрагментировать.... Может, что бы со всей этой дефрагментацией для работы с файлом отдельный процесс (thread)создавать? У него адресное пространство чистенькое будет, не фрагментированное...


Или отдельную кучу, или thread со своей кучей
PM MAIL   Вверх
_hunter
Дата 17.2.2006, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



ни первое ни второе не реализуемо. на весь процесс адресное пространство одно.


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Lotrex
Дата 17.2.2006, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 95
Регистрация: 9.2.2006
Где: Казань

Репутация: 2
Всего: 3



Цитата(_hunter @ 17.2.2006, 12:22 Найти цитируемый пост)
ни первое ни второе не реализуемо. на весь процесс адресное пространство одно.

Чтой-то я не понял, к чему это... По моему разумению, у нового процесса (CreateProcess) будет свои 2 Гб виртуальной памяти (нефрагментированной и ничем не занятой). Али я не не прав? smile

Это сообщение отредактировал(а) Lotrex - 17.2.2006, 18:45
PM MAIL ICQ   Вверх
_hunter
Дата 17.2.2006, 19:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



у процесса -- да. но не у потока этого же процесса ( как советовал threef ) и не в этом же процессе ( именно там будет создаваться вторая куча )


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Earnest
Дата 17.2.2006, 22:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Конечно, весь огромный файл отобразить в память не получится.
Да и зачем? Этот какой-то безумный перерасход виртуальной памяти...
Хочешь прозрачно работать с таким файлом как с плоским массивом, напиши простую обертку, которая будет перемещать окно MapView при необходимости. Заодно и открытие\закрытие спрячешь... Размер окна можно подобрать оптимальный, в зависимости от задачи. Мне обычно 64 К хватает.


--------------------
...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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