Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
1

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

09.09.2011, 10:36. Показов 6823. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет.
Уважаемые знатоки, вопрос в следующем)

Значит задача такая, есть некий файл бинарный.
Размер не известный (компилятору). Я его открываю, читаю все что там есть и вывожу на экран.
Подскажите как определить размер этого файла и запихать все что там есть в буфер, который как раз будет динамическим (расширяемым в зависимости от размера файла)?
Ну а затем вывести все это на экран.
Привожу свой код ниже (буфер определяю статическим). Мне это не нужно.
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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.09.2011, 10:36
Ответы с готовыми решениями:

Динамическое выделение памяти / Открытие файла с командной строки
Добрый день. Дана задача: Есть информация о альбомах, выданным музыкальной группой: название, год издания, кол-во песен, кол-во клипов,...

Оптимальное выделение памяти под считанные из файла строки
Пусть, например, у вас есть прикладная программа, которая считывает 1000 строк из файла и записывает их в динамическую память. Вы не...

Выделение памяти под указатель
Нужно с помощью указателя изменить значение переменной в функции. Но под один из них не выделяется память. Что делать? int colIndex =...

16
377 / 228 / 79
Регистрация: 24.11.2009
Сообщений: 695
09.09.2011, 10:44 2
Подскажите как определить размер этого файла
можно воспользоваться функцией stat() (объявлена в sys/stat.h). При вызове функции заполняется структура, которая содержит поле st_size - размер фаила в байтах.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 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
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 11:07 5
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Блин опоздал...
А ещё и с потенциальной ошибкой. Файл может быть больше 4Гигабайт.
Впрочем и у меня с ошибкой. Я наивно предположил, что sizeof(size_t) == sizeof(pos_type).
1
 Аватар для talis
794 / 546 / 61
Регистрация: 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
1313 / 1228 / 72
Регистрация: 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
58 / 34 / 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;
    }
А по поводу чтения по 4 байта блочно не совсем еще понял, можно поподробнее?
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
09.09.2011, 12:45 9
KorPaEv, вы в игры играете? На жёстком есть образ DVD хотя бы одной игры (желательно больше 2 Gb)? Хотя в вашем случае с int и образа mini-CD хватит, упокой Господь их души. Попробуйте прочитать такой здоровый файл вашей прогой.
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
09.09.2011, 12:46 10
Цитата Сообщение от KorPaEv Посмотреть сообщение
А по поводу чтения по 4 байта блочно не совсем еще понял, можно поподробнее?
Ты не можешь создать массив размером более, чем есть свободной памяти (на самом деле, она ещё должна быть непрерывной, поэтому всё ещё хуже).
Можешь попробовать считать какой-нибудь большой файл (видео, например) и программа упадёт из-за невозможности выделить столько памяти.
Поэтому нужно считывать файл по частям и обрабатывать его содержимое последовательно, блоками.
0
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
09.09.2011, 12:50  [ТС] 11
Цитата Сообщение от talis Посмотреть сообщение
KorPaEv, вы в игры играете? На жёстком есть образ DVD хотя бы одной игры (желательно больше 2 Gb)? Хотя в вашем случае с int и образа mini-CD хватит, упокой Господь их души. Попробуйте прочитать такой здоровый файл вашей прогой.
Поправьте, если ошибаюсь. Читать надо блочно? Создаю константу буфера фиксированного размера - 4 байта и соответственно в цикле прогоняю все 2 Gb, по 4 байта в буфер? согласен повиснем надолго...

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

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

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

В буфер такого размера, на который точно хватит памяти. Мегабайт, десять, пятдесят. Но не стопицот.
Да)) деревянный еще, туплю)
0
 Аватар для talis
794 / 546 / 61
Регистрация: 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
 Аватар для KorPaEv
58 / 34 / 8
Регистрация: 08.07.2011
Сообщений: 235
09.09.2011, 17:32  [ТС] 16
Спасибо еще раз всем за участие))) буду дерзать далее.
0
 Аватар для TheAthlete
174 / 170 / 19
Регистрация: 31.08.2010
Сообщений: 574
10.09.2011, 15:46 17
На мой вгляд, Вам нужно посмотреть в сторону "Проецируемыемых в память файлов". Этот метод позволит не заморачиваться с выделением буферов, тем более, что система не даст выделить буфер размером 2 ГБ и более.

Более подробно можете почитать в книге "Джеффри Рихтер, Кристоф Назар - Windows via C/C++. Программирование на языке Visual C++" Глава 17. Проецируемые в память файлы
1
10.09.2011, 15:46
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.09.2011, 15:46
Помогаю со студенческими работами здесь

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

Выделение памяти под массивы
int **mas1 = new int*; for (int e = 0; e &lt; q; e++) mas1 = new int; int **mas2 = new int*; for (int q = 0; q &lt; e;...

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

Выделение памяти под картинку
Здравствуйте. Кто-нибудь знает как организовать копирование и вставку рисунка с экрана? Но без использования ObjectABC.

Выделение памяти под структуры
Компилятор выдает ошибку error: expected ‘{’ before ‘)’ token в выделенной строке #define N 100 struct data{ ...


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

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

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Опции темы

Новые блоги и статьи
Язык программировани­я C++: сравнение с другими языками
Programming 06.02.2025
Современная разработка программного обеспечения предлагает множество языков программирования, каждый из которых обладает уникальными характеристиками и областями применения. C++ занимает особое место. . .
Язык программировани­я C++: достоинства и недостатки
Programming 06.02.2025
C++ считается одним из самых влиятельных языков программирования, продолжающим занимать ведущие позиции в мире разработки программного обеспечения. Этот язык появился как расширение языка C с. . .
Регулярные выражения в Python
BasicMan 06.02.2025
Регулярные выражения - это последовательности символов, определяющие правила поиска и сопоставления текстовых данных. В Python они используются для поиска подстрок, проверки соответствия текста. . .
Как создать свой мод для Майнкрафт с нуля на Java
IT_Exp 06.02.2025
Разработка мода для Minecraft начинается с правильной настройки среды разработки. Для создания мода потребуется Java Development Kit (JDK), интегрированная среда разработки и Minecraft Forge. JDK. . .
Async/await и асинхронное программировани­е в Java
IT_Exp 06.02.2025
Асинхронное программирование - это подход к организации вычислительных процессов, позволяющий приложениям эффективно использовать доступные ресурсы системы. В контексте Java этот метод приобретает. . .
Как исправить android.os.Netw­orkOnMain­Thread­Exception
hw_wired 06.02.2025
Исключение NetworkOnMainThreadException возникает при попытке выполнить сетевые операции в главном потоке Android-приложения. Главный поток отвечает за обработку пользовательского интерфейса и должен. . .
Как в Java определить, что массив содержит определенное значение
hw_wired 06.02.2025
В Java класс Arrays предлагает несколько способов для проверки наличия значений в массивах. Наиболее широко применяемый метод заключается в использовании комбинации Arrays. asList() и contains(). . . .
Как использовать virtualenv в Python. Виртуальные среды/окружения
hw_wired 06.02.2025
В Python виртуальные окружения решают одну из ключевых задач разработки - изоляцию зависимостей между проектами. Virtualenv создает отдельное пространство для каждого проекта, где устанавливаются. . .
Кнопка в HTML, которая работает как ссылка
hw_wired 06.02.2025
В HTML существует несколько подходов к созданию кнопки, которая функционирует как ссылка. Базовым элементом выступает тег button, который можно преобразовать в ссылку с помощью JavaScript. Для этого. . .
Как обновить страницу с помощью JavaScript
bytestream 06.02.2025
JavaScript предоставляет несколько базовых методов для обновления веб-страницы, которые встроены непосредственно в язык и доступны через объектную модель браузера. Основной метод обновления страницы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru