57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 235
|
|
1 | |
Размер и выделение памяти под открытие файла.09.09.2011, 10:36. Показов 6491. Ответов 16
Метки нет (Все метки)
Всем привет.
Уважаемые знатоки, вопрос в следующем) Значит задача такая, есть некий файл бинарный. Размер не известный (компилятору). Я его открываю, читаю все что там есть и вывожу на экран. Подскажите как определить размер этого файла и запихать все что там есть в буфер, который как раз будет динамическим (расширяемым в зависимости от размера файла)? Ну а затем вывести все это на экран. Привожу свой код ниже (буфер определяю статическим). Мне это не нужно. P.S. В перспективе данные файла будут подаваться в реалтайме, поэтому по этому вопросу буду рад выслушать на будущее советы. Пишу на C++, работаю с потоками поэтому fopen, seeks и т.д мне тоже не нужно. Код. Код
#include <fstream> #include <iostream> using namespace std; const unsigned int buf_size = 0x4000; //вот тут задаю сам буфер int main() { char *buffer; ifstream f_op("text", ios::binary); if (!f_op) cerr<<"Error file open"; else cout<<"File open!!! Text this file:\n"; buffer=new char(buf_size); while (!f_op.eof()) { f_op.read((char *)buffer, 1); //читаю по одному байту, тоже плохо какие идеи? В идеале мне читать надо блочно по 4 байта например, для скорости обработки текста. cout<<*buffer; } f_op.close(); delete buffer; } Неужели нет никаких идей ни у кого?((
0
|
09.09.2011, 10:36 | |
Ответы с готовыми решениями:
16
Динамическое выделение памяти / Открытие файла с командной строки Оптимальное выделение памяти под считанные из файла строки Выделение памяти под указатель Выделение памяти под структуру |
377 / 228 / 79
Регистрация: 24.11.2009
Сообщений: 695
|
|
09.09.2011, 10:44 | 2 |
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
||||||
09.09.2011, 10:59 | 3 | |||||
0
|
Заблокирован
|
||||||
09.09.2011, 11:03 | 4 | |||||
Добавлено через 41 секунду Блин опоздал...
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
09.09.2011, 11:07 | 5 |
А ещё и с потенциальной ошибкой. Файл может быть больше 4Гигабайт.
Впрочем и у меня с ошибкой. Я наивно предположил, что sizeof(size_t) == sizeof(pos_type).
1
|
09.09.2011, 12:36 | 6 |
KorPaEv, если файл over 4Gb, то у вас будут проблемы с выделением такого буфера. На 32-х системах это в принципе невозможно, на 64-х ещё такую память достать надо. Читайте порционно в небольшой буфер (4 Кб, например).
Добавлено через 5 минут Не знаю на счёт pos_type, но старый добрый сишный fpos_t может учитывать огромные файлы (у меня определён как long long). Получается через ftell( FILE*, fpos_t* ). Но это ТСу, к сожалению, не подойдёт.
1
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
09.09.2011, 12:41 | 7 |
С pos_type проблемы нет. Проблема есть с size_t, которую я использовал.
100% поддерживаю. Только буфер 64К, это минимальный считываемый блок с HDD, если я ничего не путаю.
0
|
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 235
|
|
09.09.2011, 12:42 [ТС] | 8 |
ВСЕМ СПАСИБО ЗА ОТВЕТЫ! Не успел пораньше заглянуть и закончил сам))), все сделал так же...
Код
#include <fstream> //подключаем заголовок для работы с потоками ввода вывода #include <iostream> using namespace std; int main() { //резервируем место под буфер char *buffer; //длинна файла int len_file; //поток на чтение из файла с параметром бинарника ifstream f_op; //открываем файл данных для чтения и проверяем открылся ли он f_op.open("text", ios::binary); if (!f_op) cerr<<"Error file open"; else cout<<"File open!!! Text this file:\n"; //ставлю курсор на конец файла без смещение (0) f_op.seekg(0, ios::end); //вычисляю кол-во байт до установленного курсора len_file=f_op.tellg(); //помещаю курсор вначало файла f_op.seekg(0, ios::beg); //заводим массив вычисленной длинны файла buffer=new char [len_file]; //читаю из буфера всю длинну файла f_op.read(buffer, len_file); //вывожу на экран буфер cout<<buffer; //закрываю файл f_op.close(); //чистим память delete [] buffer; return 0; }
0
|
09.09.2011, 12:45 | 9 |
KorPaEv, вы в игры играете? На жёстком есть образ DVD хотя бы одной игры (желательно больше 2 Gb)? Хотя в вашем случае с int и образа mini-CD хватит, упокой Господь их души. Попробуйте прочитать такой здоровый файл вашей прогой.
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
09.09.2011, 12:46 | 10 |
Ты не можешь создать массив размером более, чем есть свободной памяти (на самом деле, она ещё должна быть непрерывной, поэтому всё ещё хуже).
Можешь попробовать считать какой-нибудь большой файл (видео, например) и программа упадёт из-за невозможности выделить столько памяти. Поэтому нужно считывать файл по частям и обрабатывать его содержимое последовательно, блоками.
0
|
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 235
|
|
09.09.2011, 12:50 [ТС] | 11 |
Поправьте, если ошибаюсь. Читать надо блочно? Создаю константу буфера фиксированного размера - 4 байта и соответственно в цикле прогоняю все 2 Gb, по 4 байта в буфер? согласен повиснем надолго...
Тогда как поступить? Или я не понимаю чего то?
0
|
Делаю внезапно и красиво
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
|
|
09.09.2011, 12:52 | 12 |
Килобайта.))))
В буфер такого размера, на который точно хватит памяти. Мегабайт, десять, пятдесят. Но не стопицот.
0
|
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 235
|
|
09.09.2011, 12:56 [ТС] | 13 |
Продублирую пост. Создаю константу буффер фиксированного размера 4 байта. В нее помечаю считанное. Тогда один момент не понятен, где будет храниться все данные файла? если мне нужно получить доступ скажем к средней его части? циклом считывать слишком медленно. Сам уже запутался короче(
Добавлено через 1 минуту Да)) деревянный еще, туплю)
0
|
09.09.2011, 13:00 | 14 |
загружаете среднюю часть в буфер
Добавлено через 10 секунд ifstream::seekg() Добавлено через 1 минуту вообще, если вы решите, что вам нужно получить доступ к данным по определённому адресу в файле, значит, у вас есть некие данные, которые говорят, что вон по тому адресу лежит то, что тебе нужно. читаете подобную информацию в структуры
0
|
Заблокирован
|
||||||
09.09.2011, 16:15 | 15 | |||||
Если данных у тебя много в консоль их сразу cout не выведешь, делай постепенный вывод
аля
f_op.read(buffer, len_file); В buffer - не забывай ноль вконце buffer[ len_file] = '\0'; И закрывай поток сразу f_op.close(); А потом уж выводи Касательно размера файла - если ОЗУ хватает, то читай образ в оперативу а не ломай мозг постоянным считыванием из файла, время которое уйдёт на первоначальное время чтения 2 Гб с лихвой покроется постоянным почитыванием 4 кБ как тут "гуру" предлагают...Впрочем решать тебе, копошиться в файле с блошиным чтением или быстро обрабатывать данные из оперативной памяти! - касательно этого вместо этого //длинна файла int len_file; запиши unsigned long len_file - как раз на 4096 Мб хватит
0
|
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 235
|
|
09.09.2011, 17:32 [ТС] | 16 |
Спасибо еще раз всем за участие))) буду дерзать далее.
0
|
174 / 170 / 19
Регистрация: 31.08.2010
Сообщений: 573
|
|
10.09.2011, 15:46 | 17 |
На мой вгляд, Вам нужно посмотреть в сторону "Проецируемыемых в память файлов". Этот метод позволит не заморачиваться с выделением буферов, тем более, что система не даст выделить буфер размером 2 ГБ и более.
Более подробно можете почитать в книге "Джеффри Рихтер, Кристоф Назар - Windows via C/C++. Программирование на языке Visual C++" Глава 17. Проецируемые в память файлы
1
|
10.09.2011, 15:46 | |
10.09.2011, 15:46 | |
Помогаю со студенческими работами здесь
17
Выделение памяти под массивы Выделение памяти под указатель Выделение памяти под картинку Выделение памяти под структуры Выделение памяти под структуру Выделение памяти под структуру Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |