Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > работа с файлами, или как не загадить память


Автор: AmsTaFF 12.11.2009, 15:35
пишу курсоовую по С/С++, надо написать БД студентов.

проблема такова - нельзя засорять память всеми записми одновременно, и есть несколько вопросов

1. при открытии файла, он весь заносится в оперативную память? (например 2ГБ файл будет)
2. как можно собрать список(массив) файлов по шаблону, например "student_Num_%d.dat", вместо %d - ID записи идея в том, чтобы подгружать файлы с нужными ID когда понадобятся, а потом обратно выгружать из памяти.

буду очень благодарен, если будет пример кода, не всего конечно же, но чтобы понять как... , ибо сколько я не искал - по большей части проблемы в синтаксисе и с типами данных (не понимаю как переводить из LPCWSTR в const char * например) или используется Visual и такие конструкции, которые я пока понять не могу...

Автор: Abyx 12.11.2009, 18:47
AmsTaFF, 
1) нет, пока сам не скопируеш в память
2) для винды - поиском, FindFirst, FindNext

Автор: AmsTaFF 12.11.2009, 19:38
1. значит я могу открыть файл размером 1ГБ и он не будет помещен в ОЗУ, и только при считывании данных из него в переменные будет выделяться память? (извините за такие вопросы, но нету ни пособий, ни книжек нормальных в данный момент)
2. да, я уже видел пример с этим, но я не смог его запустить, есть ли пример работы с данными ф-циями?

Автор: Kipter 12.11.2009, 19:51
Цитата(AmsTaFF @  12.11.2009,  19:38 Найти цитируемый пост)
1. значит я могу открыть файл размером 1ГБ и он не будет помещен в ОЗУ, и только при считывании данных из него в переменные будет выделяться память? (извините за такие вопросы, но нету ни пособий, ни книжек нормальных в данный момент)


Операция открытия файла в стандартной библиотеке Си или Си++ не подразумевает его копирование в память, ты всего лишь получаешь Дескриптор этого фаила (своеобразный указатель на фаил выдаваемый операционной системой) если помнишь указатели не хранят значений а только на них указывают =) 
А при передаче указателя значения не копируются, так и дескриптор это какое то число - адрес для операционной системы по которому ты можешь получить доступ к файлу (т.е массиву байтов)

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

Автор: AmsTaFF 13.11.2009, 00:28
отлично, спасибо.

Тогда вопрос в догонку, как можно удалить запись из файла, например из бинарного файла структуру?

слышал про ф-цию chsize, но не могу найти библиотеку, в которой она содержится... не подскажете? или она Linux'овая, как и ftruncate?

Автор: Abyx 13.11.2009, 01:03
AmsTaFF, это делается только перезаписью файла
или перемещением структур в файле и отрезанием его конца

Автор: Enelar 13.11.2009, 01:21
внесу свой небольшой вклад.
если не хотите париться с функциями финд ферст финд некст, можно завести фаил в котором будут храниться имена файлов и соответствия индексам. а что бы не загружать прогу сильно создать еще один, в котором будет писаться - удален ли id.
А первый перезаписывать когда второй большим стал или времени много стало.

Автор: AmsTaFF 13.11.2009, 06:49
2Abyx
отрезание конца тоже подходит, но вопрос - как? я не смог найти в библиотеке ф-ции для решения данной проблемы...

2Enelar
хм, интересненько, попробую сделать

Автор: Kipter 13.11.2009, 09:49
AmsTaFF, 
Я вот точно сказать не могу есть ли кросс-платформенный способ усечения фаила, но если вы пишите под OS Windows то погуглите или поищите на форуме такую функцию как:  _chsize или SetEndOfFile

Далее, был у меня такой случай, что в фаиле я хранил набор неких структур, но каждая структура была всегда одного и того же размера.
Что я делал:
от начала фаила записывал эти одинаковые по размеру структуры последовательно...
как только какую либо из записей нужно было удалить, то в конец фаила просто записывался индекс удаленной структуры.
При добавлении новой структуры, проверялось нет ли на конце фаила индексов удаленных структур, если есть то на их место записываем новую, а индекс удаляем из конца очереди - урезанием фаила (SetEndOfFile)

данный метод подходит только если структуры фиксированного размера =)

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

Ну а когда велосипеды надоели, я просто стал прилинковывать к проектам бесплатную БД sqlite
и хранить данные уже в ней, чего и вам желаю =)


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)