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

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

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

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

07.10.2011, 22:57. Просмотров 1703. Ответов 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++):

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

Запись и чтение файлов - C++
Есть задача, имеются бинарные файл А и В, в А первые 10 чисел положительные, другие 10 отрицательные. Записать в В первые 5 положительных и...

чтение/запись файлов - C++
Здравствуйте, подскажите, пожалуйста, как решить проблему: Имеется массив типа BYTE, необходимо записать его КАК файл Microsoft Word,а...

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

Чтение/запись двоичных файлов - C++
задача,если упрощенно, записать в новый двоичный файл данные исходного файла в блоках по ,допустим, 20 байт. брал целочисленный массив...

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

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

я файл для чтения не выбираю
мне его дали и я должен максимально быстро считать матрицу из него в свой массив
0
easybudda
Модератор
Эксперт CЭксперт С++
9700 / 5650 / 964
Регистрация: 25.07.2009
Сообщений: 10,873
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 / 0
Регистрация: 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
915 / 740 / 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 до максимума ограничения далее преобразуем в числа.
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
08.10.2011, 11:00 #8
Цитата Сообщение от Coyote112358 Посмотреть сообщение
есть мнение что этот способ в два раза быстрее работает
Чьё это мнение?
С каких раз чтение "вперемешку" стало быстрее последовательного чтения?

Если тебе действительно нужно быстро, то считай сразу весь файл в память, а потом уже разбирай по словам его.
0
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;
}
Это самый быстрый вариант чтения файла или может быть еще быстрее?
0
09.10.2011, 01:13
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.10.2011, 01:13
Привет! Вот еще темы с ответами:

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

Запись и чтение файлов на диск и с диска - C++
Добрый день,помогите пожалуйста составить две программы. 1)Создать файл с полями:Фамилия,№ экзаменационного билета,зачет\незачет. ...

Чтение и запись файлов на удаленном компьютере - C++
Как послать с моего компютера на другой компютер файл, и ишьо как винять оттуда файл? Не примите за виросопистса, я в добрих намериниях.

Чтение из двух файлов и запись в третий - C++
Имеется следующая задача: в цикле подсчитывается определенное значение функции fe, зависящее от одного параметра(вводится) и записывается в...


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

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

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