Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.82
KorPaEv
56 / 32 / 4
Регистрация: 08.07.2011
Сообщений: 201
#1

Размер и выделение памяти под открытие файла. - C++

09.09.2011, 10:36. Просмотров 1547. Ответов 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;
    }
Добавлено через 3 часа 22 минуты
Неужели нет никаких идей ни у кого?((
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.09.2011, 10:36
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Размер и выделение памяти под открытие файла. (C++):

Выделение памяти под масссив - C++
Как занести данные в двумерный массив с клавиатуры? пользователь должен сам ввести размерность

Выделение памяти под указатель - C++
Здравствуйте форумчане,у меня возник маленький вопрос:) Почему sizeof(char) дает результат в 1 байт, а sizeof(char*) ) дает 4 байта.Как...

Выделение памяти под массив - C++
Требуется выделить память под матрицу. Будет ли следующий код работать корректно? //глобальная область int x_size = 3; ...

Выделение памяти под массив - C++
в массиве данных хранять в последовательных ячейках памяти В программе, выделенна память под массив, для ввода данных пользователем. ...

Выделение памяти под матрицу - C++
Всем доброго времени суток! Есть такая проблема, у меня есть свой класс Cell. Мне нужно создать матрицу объектов этого типа и выделить под...

Выделение памяти под структуру - C++
enrollee *p=new enrollee; после работы delete p; выбивает ошибку. неправильно очищаю???

16
Vladimir.
156 / 156 / 10
Регистрация: 24.11.2009
Сообщений: 375
09.09.2011, 10:44 #2
Подскажите как определить размер этого файла
можно воспользоваться функцией stat() (объявлена в sys/stat.h). При вызове функции заполняется структура, которая содержит поле st_size - размер фаила в байтах.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 10:59 #3
C++
1
2
3
4
5
6
7
8
  ifstream in;
  in.open ("name.txt", ios::binary );
  
  in.seekg (0, ios::end); // Позиционируемся в конец файла
  size_t length = in.tellg(); // Узнаём позицию (= длина файла)
  in.seekg (0, ios::beg); // Позиционируемся обратно в начало
 
  buffer = new char [length];
0
-=ЮрА=-
Заблокирован
Автор FAQ
09.09.2011, 11:03 #4
Цитата Сообщение от KorPaEv Посмотреть сообщение
Неужели нет никаких идей ни у кого?((
C++
1
2
3
4
5
6
7
8
9
ifstream f_op("text", ios::binary);
f_op.seekg(0,ios::end);//курсор вконец
long fLen = f_op.tellg();//получили позицию курсора, она равна длинне файла
f_op.seekg(0,ios::beg);//курсор вначало
 
char * str = new char[fLen + 1];//Буфер в размер файла
f_op.read(str,fLen);//Прочли весь файл в буфер
f_op.close()
str[fLen] = '\0';//Вконце строк всегда идёт мусор, отбрасываем его
Далее делай с str всё что хочешь...

Добавлено через 41 секунду
Блин опоздал...
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 11:07 #5
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Блин опоздал...
А ещё и с потенциальной ошибкой. Файл может быть больше 4Гигабайт.
Впрочем и у меня с ошибкой. Я наивно предположил, что sizeof(size_t) == sizeof(pos_type).
1
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 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
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 12:41 #7
Цитата Сообщение от talis Посмотреть сообщение
Не знаю на счёт pos_type
С pos_type проблемы нет. Проблема есть с size_t, которую я использовал.

Цитата Сообщение от talis Посмотреть сообщение
Читайте порционно в небольшой буфер (4 Кб, например)
100% поддерживаю. Только буфер 64К, это минимальный считываемый блок с HDD, если я ничего не путаю.
0
KorPaEv
56 / 32 / 4
Регистрация: 08.07.2011
Сообщений: 201
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;
    }
А по поводу чтения по 4 байта блочно не совсем еще понял, можно поподробнее?
0
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
09.09.2011, 12:45 #9
KorPaEv, вы в игры играете? На жёстком есть образ DVD хотя бы одной игры (желательно больше 2 Gb)? Хотя в вашем случае с int и образа mini-CD хватит, упокой Господь их души. Попробуйте прочитать такой здоровый файл вашей прогой.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 12:46 #10
Цитата Сообщение от KorPaEv Посмотреть сообщение
А по поводу чтения по 4 байта блочно не совсем еще понял, можно поподробнее?
Ты не можешь создать массив размером более, чем есть свободной памяти (на самом деле, она ещё должна быть непрерывной, поэтому всё ещё хуже).
Можешь попробовать считать какой-нибудь большой файл (видео, например) и программа упадёт из-за невозможности выделить столько памяти.
Поэтому нужно считывать файл по частям и обрабатывать его содержимое последовательно, блоками.
0
KorPaEv
56 / 32 / 4
Регистрация: 08.07.2011
Сообщений: 201
09.09.2011, 12:50  [ТС] #11
Цитата Сообщение от talis Посмотреть сообщение
KorPaEv, вы в игры играете? На жёстком есть образ DVD хотя бы одной игры (желательно больше 2 Gb)? Хотя в вашем случае с int и образа mini-CD хватит, упокой Господь их души. Попробуйте прочитать такой здоровый файл вашей прогой.
Поправьте, если ошибаюсь. Читать надо блочно? Создаю константу буфера фиксированного размера - 4 байта и соответственно в цикле прогоняю все 2 Gb, по 4 байта в буфер? согласен повиснем надолго...

Тогда как поступить? Или я не понимаю чего то?
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 12:52 #12
Цитата Сообщение от KorPaEv Посмотреть сообщение
по 4 байта в буфер?
Килобайта.))))

В буфер такого размера, на который точно хватит памяти. Мегабайт, десять, пятдесят. Но не стопицот.
0
KorPaEv
56 / 32 / 4
Регистрация: 08.07.2011
Сообщений: 201
09.09.2011, 12:56  [ТС] #13
Цитата Сообщение от Deviaphan Посмотреть сообщение
Ты не можешь создать массив размером более, чем есть свободной памяти (на самом деле, она ещё должна быть непрерывной, поэтому всё ещё хуже).
Можешь попробовать считать какой-нибудь большой файл (видео, например) и программа упадёт из-за невозможности выделить столько памяти.
Поэтому нужно считывать файл по частям и обрабатывать его содержимое последовательно, блоками.
Продублирую пост. Создаю константу буффер фиксированного размера 4 байта. В нее помечаю считанное. Тогда один момент не понятен, где будет храниться все данные файла? если мне нужно получить доступ скажем к средней его части? циклом считывать слишком медленно. Сам уже запутался короче(

Добавлено через 1 минуту
Цитата Сообщение от Deviaphan Посмотреть сообщение
Килобайта.))))

В буфер такого размера, на который точно хватит памяти. Мегабайт, десять, пятдесят. Но не стопицот.
Да)) деревянный еще, туплю)
0
talis
792 / 544 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
09.09.2011, 13:00 #14
Цитата Сообщение от KorPaEv Посмотреть сообщение
если мне нужно получить доступ скажем к средней его части?
загружаете среднюю часть в буфер

Добавлено через 10 секунд
ifstream::seekg()

Добавлено через 1 минуту
вообще, если вы решите, что вам нужно получить доступ к данным по определённому адресу в файле, значит, у вас есть некие данные, которые говорят, что вон по тому адресу лежит то, что тебе нужно. читаете подобную информацию в структуры
0
-=ЮрА=-
Заблокирован
Автор FAQ
09.09.2011, 16:15 #15
Цитата Сообщение от KorPaEv Посмотреть сообщение
ВСЕМ СПАСИБО ЗА ОТВЕТЫ! Не успел пораньше заглянуть и закончил сам))), все сделал так же...

А по поводу чтения по 4 байта блочно не совсем еще понял, можно поподробнее?
Если данных у тебя много в консоль их сразу cout не выведешь, делай постепенный вывод
аля

C++
1
2
3
4
5
6
7
for(int i = 0,j; i < len_file;i += 4096)
{
   for(j = 0; j < 4096; j++)
        cout<<buffer[j];
   cout<<"\r\n";
   buffer += 4096;//Сдвигаем указатель на 4096
}
- как раз по 4кБ выводить будешь

f_op.read(buffer, len_file);
В buffer - не забывай ноль вконце buffer[ len_file] = '\0';
И закрывай поток сразу
f_op.close();
А потом уж выводи

Касательно размера файла - если ОЗУ хватает, то читай образ в оперативу а не ломай мозг постоянным считыванием из файла, время которое уйдёт на первоначальное время чтения 2 Гб с лихвой покроется постоянным почитыванием 4 кБ как тут "гуру" предлагают...Впрочем решать тебе, копошиться в файле с блошиным чтением или быстро обрабатывать данные из оперативной памяти!

Цитата Сообщение от talis Посмотреть сообщение
На жёстком есть образ DVD хотя бы одной игры (желательно больше 2 Gb)
- касательно этого вместо этого
//длинна файла
int len_file;
запиши
unsigned long len_file - как раз на 4096 Мб хватит
0
09.09.2011, 16:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.09.2011, 16:15
Привет! Вот еще темы с ответами:

Выделение памяти под переменную - C++
Драсте, уважаемые. Мне надо выделить переменную на 25мег, чтоб в ней хранить все просчёты выполненые программой. (Пробовал в BCB6 и в BCW...

Выделение памяти под указатель - C++
Доброго времени суток. Возник такой вопрос: для любой программы, насколько мне известно, выделяется свой кусочек оперативной памяти. Когда...

Выделение памяти под структуру - C++
Доброго дня, товарисчи. В общем, возникла проблема при выделении памяти для структуры. Подскажите, пожалуйста, в чем ошибка. Собсна сам...

Выделение памяти под строку - C++
Никак не могу понять, в чем проблема, подскажите пожалуйста. Предположим, инициализирую переменную, ожидая получить строку из 10...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru