Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.97/104: Рейтинг темы: голосов - 104, средняя оценка - 4.97
 Аватар для programina
2062 / 619 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2

Быстрое чтение файла

11.11.2011, 10:59. Показов 20697. Ответов 71
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здраствуйте. Я пишу программу, которая читает файлы порядка от нескольких килобайтов до максимум 3 Мб. Посоветуйте пожалуйста, какие функции и/или алгоритмы использовать для максимальнобыстрого чтения данных, представленных вещественными числами. Прошу прощения, если мой вопрос неправильно сформулирован.
3
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
11.11.2011, 10:59
Ответы с готовыми решениями:

Быстрое чтение массива из файла
Добрый день, появился вроде бы не сложный вопрос, у меня есть динамический массив данных double ** data; // пусть 200x500 //я его...

Быстрое чтение и запись файлов
Вопрос такой: имеется файл input.txt следующего вида: 5 12 6 7 44 2 1 2 3 4 5 2 343 634 54 1 123 2 345 56 56 11111 2222...

Быстрое заполнение большого файла
Здравствуйте! Возникла проблема в работе с большим файлом: возникла необходимость быстро заполнять некоторый участок большого файла...

71
Эксперт С++
 Аватар для Thinker
4267 / 2241 / 203
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
11.11.2011, 14:32
Студворк — интернет-сервис помощи студентам
Строчная буферизация это когда строки до '\n' накапливаются, а потом целиком записываются, а блочная это когда не будет заполнен целиком буфер
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
11.11.2011, 14:37
Цитата Сообщение от programina Посмотреть сообщение
Thinker и Байт, спасибо вам большое. Я узнала про буферизацию потока.
Мой вам совет. Сделайте буфер побольше. И читайте столько, сколько нужно для нормальной логики программы. Хоть по одному числу.
C
1
2
3
4
5
6
7
8
FILE *f; double d; int size = sizeof(double);
f = fopen("nfvt", "rb");
setvbuf(f, NULL, _IOFBF, 10400);
while(1) {
  if (fread(&d, 1, size, f)<size) break;
  .......
}
fclose(f);
Если, конечно, в нашей дискуссии с Thinker прав окажусь я
0
Клюг
 Аватар для Charles Kludge
7677 / 3192 / 382
Регистрация: 03.05.2011
Сообщений: 8,380
11.11.2011, 14:37
IMHO, для ДОСи можно использовать
C
1
2
#include <stdio.h>
void setbuf( FILE *fp, char *buffer );
The setbuf function can be used to associate a buffer with the file designated by fp. If this function is used, it must be called after the file has been opened and before it has been read or written. If the argument buffer is
NULL, then all input/output for the file fp will be completely unbuffered. If the argument buffer is not NULL, then it must point to an array that is at least BUFSIZ characters in length, and all input/output will be fully buffered.
и
C
1
2
3
4
5
#include <stdio.h>
int setvbuf( FILE *fp,
             char *buf,
             int mode,
             size_t size );
The setvbuf function can be used to associate a buffer with the file designated by fp. If this function is used, it must be called after the file has been opened and before it has been read or written. The argument mode determines how the file fp will be buffered, as follows:


Mode Meaning

_IOFBF

causes input/output to be fully buffered.


_IOLBF

causes output to be line buffered (the buffer will be flushed when a new-line character is written, when the buffer is full, or when input is requested on a line buffered or unbuffered stream).


_IONBF

causes input/output to be completely unbuffered.

If the argument buf is not NULL, the array to which it points will be used instead of an automatically allocated buffer. The argument size specifies the size of the array.
А под виндой
C
1
2
3
4
5
6
7
8
9
HANDLE CreateFileMapping(
 
    HANDLE hFile,   // handle to file to map 
    LPSECURITY_ATTRIBUTES lpFileMappingAttributes,  // optional security attributes 
    DWORD flProtect,    // protection for mapping object 
    DWORD dwMaximumSizeHigh,    // high-order 32 bits of object size  
    DWORD dwMaximumSizeLow, // low-order 32 bits of object size  
    LPCTSTR lpName  // name of file-mapping object 
   );
и иже с ним.
0
Эксперт С++
 Аватар для Thinker
4267 / 2241 / 203
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
11.11.2011, 14:40
Цитата Сообщение от Байт Посмотреть сообщение
Сделайте буфер побольше.
Только если он в стек поместится, а то можно динамический массив создать и работать с "rb" или "wb".
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
11.11.2011, 14:42
Цитата Сообщение от Thinker Посмотреть сообщение
Это хорошо, но в двоичных потоках нет буферизации. Столкнулся с этим, когда серьезные и быстрые программы шифрования писал.
Отложим дискуссию. Вот придумаю грамотный эксперимент, посмотрим.
0
Эксперт С++
 Аватар для Thinker
4267 / 2241 / 203
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
11.11.2011, 14:43
Цитата Сообщение от Байт Посмотреть сообщение
Отложим дискуссию. Вот придумаю грамотный эксперимент, посмотрим.
Ок, советую с копированием файлов
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 14:44
Цитата Сообщение от Charles Kludge Посмотреть сообщение
CreateFileMapping
Мне казалось, что она просто "выводит" файл в адресное пространство программы. Про буферизацию я ничего на msdn не увидел
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
11.11.2011, 14:45
Цитата Сообщение от Thinker Посмотреть сообщение
Только если он в стек поместится, а то можно динамический массив создать и работать с "rb" или "wb".
setvbuf при втором параметре = NULL сам выделяет память посредством
malloc, т.е. в динамической памяти
1
Эксперт С++
 Аватар для Thinker
4267 / 2241 / 203
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
11.11.2011, 14:47
Цитата Сообщение от Байт Посмотреть сообщение
setvbuf при втором параметре = NULL сам выделяет память посредством
malloc, т.е. в динамической памяти
Я про собственный буфер, мы же дискутируем, что setbuf для двоичного формата не подходит, поэтому со своей стороны предлагаю свой динамический буфер создать
1
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
11.11.2011, 15:01
Цитата Сообщение от programina Посмотреть сообщение
Здраствуйте. Я пишу программу, которая читает файлы порядка от нескольких килобайтов до максимум 3 Мб. Посоветуйте пожалуйста, какие функции и/или алгоритмы использовать для максимальнобыстрого чтения данных, представленных вещественными числами. Прошу прощения, если мой вопрос неправильно сформулирован.
- файл совсем маханький предлагаю всё его содержимое сразу впихнуть в буффер, а затем уже работать с алгоритмами для строки или чего вы там хотите реализовать!Работа с буффером будет куда более быстрой чем парсинг файлового потока!Да и файл можно без опасения переписать, все данные то в буфере
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
long sLen;
char *s;
FILE * f = fopen("fPath","rb");//да rb - не будет граблей с \r\n
if(f)
{
    fseek(f,0,SEEK_END);//Курсор вконец
    sLen = ftell(f);//Узнаём длинну файла
    fseek(f,0,SEEK_SET);//Курсор вначала
    if(!(str = (char *)malloc(sizeof(char) * (sLen + 1))))
           printf("Allocation memory error\n");
    else
    {
          fread(s,sLen,1,f);
          s[sLen] = '\0';//Завершили строку
    }
    fclose(f);//Закрыли файловый поток
    if(s)
   {
           //работаем с инфойфайла
   }
}
Добавлено через 5 минут
Чтобы перебить строку в вещественные числа strtok-ом парсим токены идущие через пробел
char delim[] = " ";
C
1
2
3
4
5
6
char * tok = strtok(str,delim);
while(tok)
{
    arr[i++] = atof(tok);
    tok = strtok(str,delim);
}
Добавлено через 1 минуту
Ну а на плюсах можно всем что выше написал не заморачиваться и сделать вот так
программа с динамической памятью
тут уже готовый проект считывания ifstream-ом
1
11.11.2011, 15:03

Не по теме:

-=ЮрА=-, но вопрос то такой: происходит ли автоматическая буферизация двоичных потоков

0
 Аватар для programina
2062 / 619 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
11.11.2011, 15:15  [ТС]
Не по теме:
Спасибо всем большое, но у меня уже переполнение буфера в голове от такого кол-ва информации.
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
11.11.2011, 16:37
Всё же я посьавил себе за цель проверить свои слова о быстроте,
для полноты анализа рассматривал сразу 3 алгоритма чтения вещественных в массив
1 - й вариант fscanf
2 - й буффер а затем подхват всего strtok-ом и atof-ом
3 - й любимый многими начинающими вариант ifstream>>
Пришлось написать заполнитель файла - мой файл содержит 656898 double и весит 3,75 Мб)
(вбивать вручную 3 Мб чисел я бы засел на дня 2)
так что цепляю и код рандомного наполнителя файла тоже
(наполняет файл долго - около 15 сек, ну дык и значений почти 660 тысяч)
fill.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;
 
int main()
{
    double val;
    cout<<"Enter num of elements : ";
    long num;cin>>num;
    ofstream ofs("file.txt");
    ofs<<num<<endl;
    srand(time(0));
    for(long i = 0; i < num; i++)
    {
        cout<<(val = rand()%(2*num)/(1.0 + rand()%2));
        ofs<<val;
        if(i != num - 1)
        {
            cout<<" ";
            ofs<<" ";
        }
        else
            cout<<"\n";
    }
    ofs.close();
    system("pause");
    return 0;
}


Сам алгоритм чтения здесь
read.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;
double * parse_fscanf(long &n, double * arr);
double * parse_strtok(long &n, double * arr);
double * parse_ifstrm(long &n, double * arr);
 
int main()
{
    long n,bgn,end;
    double * arr = NULL;
    cout<<"\tVariant C(fscanf)\n";
    time(&bgn);
    cout<<"Algorithm started at : "<<asctime(localtime(&bgn));
    arr = parse_fscanf(n, arr);
    time(&end);
    cout<<"Algorithm stoped at : "<<asctime(localtime(&end));
    cout<<"Time of work : "<<difftime(end,bgn)<<" sec"<<endl;
    cout<<"arr["<<0<<"] = "<<arr[0]<<endl;
    cout<<"arr["<<n - 1<<"] = "<<arr[n - 1]<<endl;
    delete [] arr;
 
    cout<<"\tVariant C(strtok)\n";
    time(&bgn);
    cout<<"Algorithm started at : "<<asctime(localtime(&bgn));
    arr = parse_strtok(n, arr);
    time(&end);
    cout<<"Algorithm stoped at : "<<asctime(localtime(&end));
    cout<<"Time of work : "<<difftime(end,bgn)<<" sec"<<endl;
    cout<<"arr["<<0<<"] = "<<arr[0]<<endl;
    cout<<"arr["<<n - 1<<"] = "<<arr[n - 1]<<endl;
    delete [] arr;
 
    cout<<"\tVariant C++(ifstream)\n";
    time(&bgn);
    cout<<"Algorithm started at : "<<asctime(localtime(&bgn));
    arr = parse_ifstrm(n, arr);
    time(&end);
    cout<<"Algorithm stoped at : "<<asctime(localtime(&end));
    cout<<"Time of work : "<<difftime(end,bgn)<<" sec"<<endl;
    cout<<"arr["<<0<<"] = "<<arr[0]<<endl;
    cout<<"arr["<<n - 1<<"] = "<<arr[n - 1]<<endl;
    delete [] arr;
 
    system("pause");
    return 0;
}
 
double * parse_fscanf(long &n, double * arr)
{
    FILE * file = fopen("file.txt","rb");
    if(!file)
        cout<<"Error open file.txt\n";
    else
    {
        fscanf(file,"%u",&n);
        arr = new double[n];
        for(long i = 0; i < n; i++)
            fscanf(file,"%lf",&arr[i]);
        fclose(file);
    }
    return arr;
}
 
double * parse_strtok(long &n, double * arr)
{
    char * tok;
    char * str;
    char delim[] = " \n";
    long i,sLen;
    FILE * file = fopen("file.txt","rb");
    if(!file)
        cout<<"Error open file.txt\n";
    else
    {
        fseek(file,0,SEEK_END);
        sLen = ftell(file);
        fseek(file,0,SEEK_SET);
        if(!(str = (char *)malloc(sizeof(char)*(sLen + 1))))
            cout<<"Allocation memory error\n";
        else
        {
            fread(str,1,sLen,file);
            str[sLen] = '\0';
        }
        fclose(file);
        if(str)
        {
            
            tok = strtok(str,delim);
            n = atoi(tok);i = 0;
            arr = new double[n];
            tok = strtok(NULL,delim);
            while(tok)
            {
                arr[i++] = atof(tok);
                tok = strtok(NULL,delim);
            }
        }
    }
    return arr;
}
 
double * parse_ifstrm(long &n, double * arr)
{
    ifstream ifs("file.txt");
    if(!ifs)
        cout<<"Error open file.txt\n";
    else
    {
        ifs>>n;
        arr = new double[n];
        for(long i = 0; i < n && !ifs.eof(); i++)
            ifs>>arr[i];
        ifs.close();
    }
    return arr;
}


Сравнительная таблица на миниатюре. Как видим быстро отработали 1-й и 2-й варианты, но
спешу заметить посмотрите сколько операций именно во 2-м варианте - в два раза больше чем в
1-м, а время работы идентично, так что выводы делайте сами...
PS:Плюсовый вариант прямого чтения ifstream>> явообще отбросил для себя
(даже и не думал что это такой ужас в плане времени)
Миниатюры
Быстрое чтение файла   Быстрое чтение файла  
1
 Аватар для programina
2062 / 619 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
11.11.2011, 18:44  [ТС]
Если не использовать cout, то на заполнение файла у меня ушло ~5 сек
Чтение фсканфом у меня в 4 раза быстрее чем ifstream
А strtok у меня not declared in this scope
0
278 / 174 / 21
Регистрация: 10.07.2011
Сообщений: 441
11.11.2011, 18:47
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
спешу заметить посмотрите сколько операций именно во 2-м варианте - в два раза больше чем в 1-м, а время работы идентично, так что выводы делайте сами...
осмелюсь предположить что fscanf за сценой делает аналогичные операции что и strtok и atof вместе взятые. отсюда и одинаковое время.
з.ы. было бы информативно проверить результаты действия разных вариантов с точносттю не до секунды, а до миллисекунды. возможно разница всетаки есть.
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
11.11.2011, 18:50
Вот
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <time.h>
 
#define afc(j,n) for(j=0; j<n; j++)  // Пара макросов, украшающих жизнь
#define SD sizeof(double)
 
main()
{  time_t Beg, End; int k;
 
  // full();
  afc(k,2) {
    Beg = time(NULL);
    readx(k);
    End = time(NULL);
    printf("k=%d Time=%f sec\n", k, difftime(End, Beg));
  }
}
/************/
full()
{ double d=3.14; FILE *f; long j;
 
   f = fopen("test.tst", "wb");
   printf("full:bsize=%d buffer=%d\n", f->bsize, f->buffer!=NULL);
   afc(j,4000000L) fwrite(&d, 1, SD, f);
   fclose(f);
}
/*************/
readx(int k)
{ double d; FILE *f;
 
   f = fopen("test.tst", "rb");
   if (k) setvbuf(f, NULL, _IONBF, 0);
   printf("%d:bsize=%d buffer=%d\n", k, f->bsize, f->buffer!=NULL);
   while(fread(&d, SD, 1, f)==1);
   fclose(f);
}
/*************/
/* Результат:
0:bsize=512 buffer=1
k=0 Time=1.000000 sec
1:bsize=0 buffer=1
k=1 Time=61.000000 sec
*/
Thinker, сдавайтесь!
2
 Аватар для programina
2062 / 619 / 41
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
11.11.2011, 19:04  [ТС]
У меня не работает

error: 'readx' was not declared in this scope
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 19:09
допишите вверх под макросы:

C
1
2
int readx( int );
int full();
1
278 / 174 / 21
Регистрация: 10.07.2011
Сообщений: 441
11.11.2011, 19:09
Цитата Сообщение от programina Посмотреть сообщение
error: 'readx' was not declared in this scope
это потому что функция main объявлена раньше функции readx.
поменяйте местами или объявите прототипы.
1
11.11.2011, 19:10

Не по теме:

Байт, а это что у вас за компилятор, который нашёл функции без объявления перед использованием?

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.11.2011, 19:10
Помогаю со студенческими работами здесь

Быстрое преобразование фурье wave файла
Всем доброго времени суток! Сейчас работаю над дипломом, в c++ как и в обработке звука пока новичок. На данном этапе мне необходимо...

Максимальное быстрое создание большого файла
У кого какие алгоритмы создания максимально быстро файлов, больших размеров?

Быстрое считывание 32кб из файла 7гб
Есть бинарный файл размером 6,95 ГБ, он представляет из себя массив short. Необходимо быстро считать случайные 65536 шортов. Т.к. весь файл...

Быстрое создание пустого файла определенного размера
Добрый день Столкнулся с проблемой как можно очень быстро создать файл на жестком диске, заполнены нулями (или мусором) за малый...

Быстрое создание бинарного файла заданного размера
Собственно, вопрос в теме. Как быстро выделить память под файл? Можно, конечно, методично записать в файл массив необходимого размера, но...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru