Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Coyote112358
0 / 0 / 2
Регистрация: 17.11.2009
Сообщений: 22
#1

Быстрое чтение и запись файлов - C++

07.10.2011, 22:57. Просмотров 1821. Ответов 8
Метки нет (Все метки)

Вопрос такой:

имеется файл 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 333 44 5

первое число (может быть любое типа int) - количество строк и столбцов матрицы
элементы матрицы - типа int

этот файл может быть очень большим, например первое число 5000 и соответственно матрица 5000х5000

требуется
максимально быстро его прочитать
т. е. первым делом прочитать первое число , записать в int N например
затем создать массив int размера NxN и заполнить его числами из файла

я подумываю о memory mapped file

а как это делается ? покажите пожалуйста
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.10.2011, 22:57
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Быстрое чтение и запись файлов (C++):

Чтение\запись файлов
Помогите с такой проблемой: записываю в бинарный файл числа типа long double,...

чтение/запись файлов
Здравствуйте, подскажите, пожалуйста, как решить проблему: Имеется массив типа...

Запись и чтение файлов
Есть задача, имеются бинарные файл А и В, в А первые 10 чисел положительные,...

Запись и чтение двоичных файлов
Здравствуйте! Как производится запись в двоичные файлы? Нормальных гайдов я не...

C++ - Fortran (чтение и запись файлов)
Добрый день! Средствами языка Fortran создается бинарный файл прямого...

Запись, чтение, удаление из файлов
Добрый день! Решаю задачку: 1) Нужно записать в файл - моя программа...

8
easybudda
Модератор
Эксперт CЭксперт С++
10021 / 5944 / 1483
Регистрация: 25.07.2009
Сообщений: 11,231
07.10.2011, 23:21 #2
Coyote112358, вопрос: почему бы бинарный файл не использовать, если так скорость важна? Отражение в память удобно использовать, когда нужен произвольный доступ к содержимому файла, суперскорости считывания вы так не добьётесь...
0
Coyote112358
0 / 0 / 2
Регистрация: 17.11.2009
Сообщений: 22
07.10.2011, 23:28  [ТС] #3
а это как - использовать бинарный файл ?

я файл для чтения не выбираю
мне его дали и я должен максимально быстро считать матрицу из него в свой массив
0
easybudda
Модератор
Эксперт CЭксперт С++
10021 / 5944 / 1483
Регистрация: 25.07.2009
Сообщений: 11,231
08.10.2011, 00:08 #4
Цитата Сообщение от Coyote112358 Посмотреть сообщение
а это как - использовать бинарный файл ?

я файл для чтения не выбираю
мне его дали и я должен максимально быстро считать матрицу из него в свой массив
То есть файл текстовый, а следовательно быстро его содержимым заполнить матрицу с числами по-моему не получится - числа из текстового представления всё равно прийдётся переводить. Тупой способ:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FILE * f;
int ** matrix, rows, columns, i, j;
//...
if ( fscanf(f, "%d %d", &rows, &columns) != 2 )
    // error
if ( ( matrix = malloc(sizeof(int*) * rows) ) == NULL )
    // error
for ( i = 0; i < rows; ++i )
    if ( ( matrix[i] = malloc(sizeof(int) * cumns) ) == NULL )
        // error
for ( i = 0; i < rows; ++i )
    for ( j = 0; j < columns; ++j )
        if ( fscanf(f, "%d", &matrix[i][j]) != 1 )
            // error
//...
0
Coyote112358
0 / 0 / 2
Регистрация: 17.11.2009
Сообщений: 22
08.10.2011, 01:52  [ТС] #5
так понятно
по одному числу читаем и в массив

а как сделать с помощью memory mapped file
есть мнение что этот способ в два раза быстрее работает
0
alkagolik
Заблокирован
08.10.2011, 06:13 #6
Coyote112358, все немного иначе. суть метода в очистке кеша процессора, если вы работаете в unix, наберите man mmap там все детально расписано.
0
xAtom
917 / 742 / 299
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
08.10.2011, 07:51 #7
Цитата Сообщение от Coyote112358 Посмотреть сообщение
максимально быстро его прочитать
В текстовом режиме время будет во основном тратиться в преобразование текста в числа, в двоичном всё будет быстрее, ну вот накидал код при помощи файла отображаемого на память, самое главная проблема ещё раз повторюсь это преобразование.
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
#include <stdio.h>
#include <windows.h>
 
int main(){
  int col = 0,  
      row= 0, 
      len = 0, 
      pos = 0, 
   **mat = NULL;
   char   slen[8];
   char*  buf;
   DWORD  size;
   HANDLE fmap;
   HANDLE fp = CreateFile("D:\\matrix.txt", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0u, NULL);
   if(fp == INVALID_HANDLE_VALUE)
       exit(1);
   if((size = GetFileSize(fp, NULL)) == 0xFFFFFFFF)
          GetFileSize(fp, &size);
   if(size == 0u) {
         CloseHandle(fp);
         exit(2);
  }
   // проецировать будем только для чтения
   fmap = CreateFileMapping(fp, NULL, PAGE_READONLY, 0u, 0u, NULL);
   if(! fmap) {
        CloseHandle(fp);
        exit(3);
   }
   // отобразим файл на начальный адрес указателя для считывания
   buf = (char*) MapViewOfFile(fmap, FILE_MAP_READ, 0u, 0u, 0u);
   if(! buf) {
        CloseHandle(fmap);
        CloseHandle(fp);
        exit(3);
  }
   // здесь критическое место 
   len = col = row = pos = 0;
   if(sscanf(buf, "%s[^\n]%n", slen, &pos) == 1) {
         len = atoi(slen);
         mat = new int*[len];
         for(int i = 0; i < len; i++)
              mat[i] = new int[len];
         buf += strlen(slen);
         while(sscanf(buf, "%d%n", &mat[row][col], &pos) == 1) {
               if(++col >= len) {
                    row++;
                    col = 0;
                }
                buf += pos;
          }
  }
  UnmapViewOfFile((LPCVOID)fmap);
  CloseHandle(fmap);
  CloseHandle(fp);
 
   /* тест
   for(int r = 0; r < len; r++) {
         for(int c = 0; c < len; c++)
               printf("%d ", mat[r][c]);
         putchar('\n');
   }
   */
 
   // после работы с матрицой освободить память
   for(int i = 0; i < len; i++)
        delete[] mat[i];
   delete[] mat;
   mat = NULL;
   getchar();
   return 0;
}
Coyote112358, какие размеры файла ограничивают использовать только кучу, открываем файл узнаём размер его, выделяем память под буфер далее читаем блоком ну можно указать ещё файловый буфер по больше функциями setbuf/setvbuf до максимума ограничения далее преобразуем в числа.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
08.10.2011, 11:00 #8
Цитата Сообщение от Coyote112358 Посмотреть сообщение
есть мнение что этот способ в два раза быстрее работает
Чьё это мнение?
С каких раз чтение "вперемешку" стало быстрее последовательного чтения?

Если тебе действительно нужно быстро, то считай сразу весь файл в память, а потом уже разбирай по словам его.
0
Coyote112358
0 / 0 / 2
Регистрация: 17.11.2009
Сообщений: 22
09.10.2011, 01:13  [ТС] #9
покажите пожалуйста как конкретно это сделать с моим файлом

input.txt:
3
1 2 3
4 5 6
7 8 9

?

Добавлено через 13 часов 57 минут
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
121
122
123
124
125
126
127
128
129
130
131
132
#include <stdio.h>
#include <stdlib.h>
#include "iostream"
using namespace std;
 
int main ()
{
    FILE * pFile;
    long lSize;
    char * buffer;
    size_t result;
 
    pFile = fopen ( "input.txt" , "rb" );
    
    if (pFile==NULL)
    {
        fputs ("File error",stderr);
        exit (1);
    }
 
    // obtain file size:
    fseek (pFile , 0 , SEEK_END);
    lSize = ftell (pFile);
    rewind (pFile);
 
    // allocate memory to contain the whole file:
    buffer = (char*) malloc (sizeof(char)*lSize);
 
    if (buffer == NULL)
    {
        fputs ("Memory error",stderr);
        exit (2);
    }
 
    // copy the file into the buffer:
    result = fread (buffer,1,lSize,pFile);
 
    if (result != lSize)
    {
        fputs ("Reading error",stderr);
        exit (3);
    }
 
    /* the whole file is now loaded in the memory buffer. */
 
    // terminate
    fclose (pFile);
 
    for (int i=0; i<lSize; i++)
    {
        cout << i << "  " << buffer[i] << endl;
    }
 
    int SizeOfMatrix = 0, Counter = 0, k=1;
    while (buffer[Counter]>='0' && buffer[Counter]<='9')
    {
        Counter = Counter + 1;
        cout << "Counter=" << Counter << endl;
    }
    for (int i=Counter-1; i>=0; i--)
    {
        SizeOfMatrix = SizeOfMatrix + (buffer[i]-'0')*k;
        k=k*10;
    }
    cout << "SizeOfMatrix=" << SizeOfMatrix << endl;
 
    int **Matrix = new int * [SizeOfMatrix];
    for (int i=0; i<SizeOfMatrix; i++)
    {
        Matrix[i] = new int [SizeOfMatrix];
    }
    for (int i=0; i<SizeOfMatrix; i++)
    {
        for (int j=0; j<SizeOfMatrix; j++)
        {
            Matrix[i][j]=0;
        }
    }
 
    Counter=Counter+2;
    bool Flag = 0;
    int Signum;
    int CurrentNumber;
    int Row=0, Column=0;
    while (Counter<lSize)
    {
        Signum=1;
        Flag=0;
        if (buffer[Counter]='-')
        {
            Signum=-1;
            Counter=Counter+1;
        }
        CurrentNumber=0;
        while (buffer[Counter]>='0' && buffer[Counter]<='9')
        {
            CurrentNumber=CurrentNumber*10 + buffer[Counter]-'0';
            Counter=Counter+1;
            Flag=1;
        }
        if (Flag)
        {
            if (Column==SizeOfMatrix)
            {
                Row=Row+1;
                Column=0;
            }
            Matrix[Row][Column] = Signum*CurrentNumber;
            Column=Column+1;
        }
        Counter=Counter+1;
    }
 
    cout << endl;
    for (int i=0; i<SizeOfMatrix; i++)
    {
        for (int j=0; j<SizeOfMatrix; j++)
        {
            cout << Matrix[i][j] << "   ";
        }
        cout << endl;
    }
 
    free (buffer);
    for (int m=0; m<SizeOfMatrix; m++)
    {
        delete [] Matrix[m];
    }
    delete [] Matrix;
    system("pause");
    return 0;
}
что-то не получается из одномерного массива числа переписать в двумерный

Добавлено через 11 минут
Извиняюсь

Предлагаю вот такой вариант оценить
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
121
122
123
124
125
126
127
128
129
130
131
132
#include <stdio.h>
#include <stdlib.h>
#include "iostream"
using namespace std;
 
int main ()
{
    FILE * pFile;
    long lSize;
    char * buffer;
    size_t result;
 
    pFile = fopen ( "input.txt" , "rb" );
    
    if (pFile==NULL)
    {
        fputs ("File error",stderr);
        exit (1);
    }
 
    // obtain file size:
    fseek (pFile , 0 , SEEK_END);
    lSize = ftell (pFile);
    rewind (pFile);
 
    // allocate memory to contain the whole file:
    buffer = (char*) malloc (sizeof(char)*lSize);
 
    if (buffer == NULL)
    {
        fputs ("Memory error",stderr);
        exit (2);
    }
 
    // copy the file into the buffer:
    result = fread (buffer,1,lSize,pFile);
 
    if (result != lSize)
    {
        fputs ("Reading error",stderr);
        exit (3);
    }
 
    /* the whole file is now loaded in the memory buffer. */
 
    // terminate
    fclose (pFile);
 
    for (int i=0; i<lSize; i++)
    {
        cout << i << "  " << buffer[i] << endl;
    }
 
    int SizeOfMatrix = 0, Counter = 0, k=1;
    while (buffer[Counter]>='0' && buffer[Counter]<='9')
    {
        Counter = Counter + 1;
        cout << "Counter=" << Counter << endl;
    }
    for (int i=Counter-1; i>=0; i--)
    {
        SizeOfMatrix = SizeOfMatrix + (buffer[i]-'0')*k;
        k=k*10;
    }
    cout << "SizeOfMatrix=" << SizeOfMatrix << endl;
 
    int **Matrix = new int * [SizeOfMatrix];
    for (int i=0; i<SizeOfMatrix; i++)
    {
        Matrix[i] = new int [SizeOfMatrix];
    }
    for (int i=0; i<SizeOfMatrix; i++)
    {
        for (int j=0; j<SizeOfMatrix; j++)
        {
            Matrix[i][j]=0;
        }
    }
 
    Counter=Counter+2;
    bool Flag = 0;
    int Signum;
    int CurrentNumber;
    int Row=0, Column=0;
    while (Counter<lSize)
    {
        Signum=1;
        Flag=0;
        if (buffer[Counter]=='-')
        {
            Signum=-1;
            Counter=Counter+1;
        }
        CurrentNumber=0;
        while (buffer[Counter]>='0' && buffer[Counter]<='9')
        {
            CurrentNumber=CurrentNumber*10 + buffer[Counter]-'0';
            Counter=Counter+1;
            Flag=1;
        }
        if (Flag)
        {
            if (Column==SizeOfMatrix)
            {
                Row=Row+1;
                Column=0;
            }
            Matrix[Row][Column] = Signum*CurrentNumber;
            Column=Column+1;
        }
        Counter=Counter+1;
    }
 
    cout << endl;
    for (int i=0; i<SizeOfMatrix; i++)
    {
        for (int j=0; j<SizeOfMatrix; j++)
        {
            cout << Matrix[i][j] << "   ";
        }
        cout << endl;
    }
 
    free (buffer);
    for (int m=0; m<SizeOfMatrix; m++)
    {
        delete [] Matrix[m];
    }
    delete [] Matrix;
    system("pause");
    return 0;
}
Это самый быстрый вариант чтения файла или может быть еще быстрее?
0
09.10.2011, 01:13
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.10.2011, 01:13
Привет! Вот еще темы с решениями:

Чтение/запись двоичных файлов
задача,если упрощенно, записать в новый двоичный файл данные исходного файла в...

Чтение и запись файлов на удаленном компьютере
Как послать с моего компютера на другой компютер файл, и ишьо как винять оттуда...

Чтение из двух файлов и запись в один
Помогите с одной задачей. У меня есть два файла: 1. &quot;oldmast.dat&quot; в котором 4...

Запись и чтение файлов на диск и с диска
НАПИСАТЬ ДВЕ ПРОГРАММЫ 1) СОЗДАНИЯ ФАЙЛА С УКАЗАННЫМИ ПОЛЯМИ И 2) СЧИТЫВАНИЕ...


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

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

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