Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.73
Coyote112358
0 / 0 / 0
Регистрация: 17.11.2009
Сообщений: 22
07.10.2011, 22:57     Быстрое чтение и запись файлов #1
Вопрос такой:

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

а как это делается ? покажите пожалуйста
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.10.2011, 22:57     Быстрое чтение и запись файлов
Посмотрите здесь:

Чтение из двух файлов и запись в третий C++
Чтение\запись файлов C++
Запись и чтение файлов на диск и с диска C++
Запись и чтение файлов на диск и с диска C++
C++ чтение/запись файлов
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
07.10.2011, 23:21     Быстрое чтение и запись файлов #2
Coyote112358, вопрос: почему бы бинарный файл не использовать, если так скорость важна? Отражение в память удобно использовать, когда нужен произвольный доступ к содержимому файла, суперскорости считывания вы так не добьётесь...
Coyote112358
0 / 0 / 0
Регистрация: 17.11.2009
Сообщений: 22
07.10.2011, 23:28  [ТС]     Быстрое чтение и запись файлов #3
а это как - использовать бинарный файл ?

я файл для чтения не выбираю
мне его дали и я должен максимально быстро считать матрицу из него в свой массив
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9373 / 5423 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
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
//...
Coyote112358
0 / 0 / 0
Регистрация: 17.11.2009
Сообщений: 22
08.10.2011, 01:52  [ТС]     Быстрое чтение и запись файлов #5
так понятно
по одному числу читаем и в массив

а как сделать с помощью memory mapped file
есть мнение что этот способ в два раза быстрее работает
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
08.10.2011, 06:13     Быстрое чтение и запись файлов #6
Coyote112358, все немного иначе. суть метода в очистке кеша процессора, если вы работаете в unix, наберите man mmap там все детально расписано.
xAtom
 Аватар для xAtom
910 / 735 / 60
Регистрация: 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 до максимума ограничения далее преобразуем в числа.
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
08.10.2011, 11:00     Быстрое чтение и запись файлов #8
Цитата Сообщение от Coyote112358 Посмотреть сообщение
есть мнение что этот способ в два раза быстрее работает
Чьё это мнение?
С каких раз чтение "вперемешку" стало быстрее последовательного чтения?

Если тебе действительно нужно быстро, то считай сразу весь файл в память, а потом уже разбирай по словам его.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.10.2011, 01:13     Быстрое чтение и запись файлов
Еще ссылки по теме:

C++ Запись и чтение двоичных файлов
Чтение из двух файлов и запись в один C++
Чтение и запись файлов на удаленном компьютере C++

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

Или воспользуйтесь поиском по форуму:
Coyote112358
0 / 0 / 0
Регистрация: 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;
}
Это самый быстрый вариант чтения файла или может быть еще быстрее?
Yandex
Объявления
09.10.2011, 01:13     Быстрое чтение и запись файлов
Ответ Создать тему
Опции темы

Текущее время: 11:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru