Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/18: Рейтинг темы: голосов - 18, средняя оценка - 4.56
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
1

Есть очень много маленьких текстовых файлов необходимо слить в один файл

05.01.2014, 03:03. Показов 3341. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Очень много маленьких файлов размером от 500 КБ до 90 МБ. Максимальная длина строки в файлах 80 символов.
Всего таких файлов может быть от 2 гигабайт и более. Посоветуйте, как подступиться к программе чтобы она работала максимально быстро.
Вот что я намудрил пока. Чтение и запись с помощью С++ отпадает слишком медленно или я не знаю как по другому. Сижу под Win 7.

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
        list<wstring> allPathFilesPdn = get_path_pdn(pathIn, ext); // получаем пути к файлам
        for (auto it = allPathFilesPdn.cbegin(); it != allPathFilesPdn.cend(); ++it) {
            read_and_write(*it, pathAddWriteFilePDN);
        }
 
 
 
void FindToPdnBase::read_and_write(const wstring &pathRead, const wstring &pathAddWrite) {
    FILE * pFileRead = _wfopen ( pathRead.c_str() , L"rb" );
 
    int seekres = fseek (pFileRead, 0, SEEK_END);
 
    long lSize = ftell (pFileRead);
    char *buffer = (char*) malloc (sizeof(char)*lSize);
 
    rewind (pFileRead);
    size_t result = fread (buffer,1,lSize,pFileRead);
 
    fclose (pFileRead);
 
    FILE * pFileWrite = _wfopen ( pathAddWrite.c_str(), L"ab" );
 
    size_t written = fwrite (buffer, sizeof(char), result, pFileWrite);
 
    fclose (pFileWrite);
 
    free (buffer);
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.01.2014, 03:03
Ответы с готовыми решениями:

Слить много текстовых файлов в несколько, по названию
Задача: есть несколько папок с текстовыми файлами .doc ( внутри одной папки названия файлов вида...

Много маленьких файлов .txt в один и отправка в excel
Добрый день. Не подскажите , есть папка, в ней текстовые файлы, штук сто. Названия вида 015_08_26 ...

Как слить несколько файлов в один файл?
Ну да!!!...Ну подскажите же, как слить несколько файлов в один файл, и как потом их обратно...

Разбить один m-файл на кучу маленьких m-файлов
Здравствуйте. Я не новичок в Matlab. Однако просто раньше такого не требовалось. У меня ну просто...

13
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
05.01.2014, 03:38 2
Когда-то выяснял какими функциями быстрее всего работать с файлами. Получилось, что самые быстрые - это С-функции пстрочного чтения/записи: fgets(), fputs(). Файл нужно открывать в бинарном режиме, это убыстряет работу этих функций (почему - не знаю, но факт). Насколько знаю, работа с динамической памятью - это медленно, поэтому лучше использовать массив на стеке под размер строки (тем более, размер известен).
1
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
05.01.2014, 03:41  [ТС] 3
Цитата Сообщение от alsav22 Посмотреть сообщение
Когда-то выяснял какими функциями быстрее всего работать с файлами. Получилось, что самые быстрые - это С-функции пстрочного чтения/записи: fgets(), fputs(). Файл нужно открывать в бинарном режиме, это убыстряет работу этих функций (почему - не знаю, но факт). Насколько знаю, работа с динамической памятью - это медленно, поэтому лучше использовать массив на стеке под размер строки (тем более, размер известен).
Спасибо. Сейчас попробую.
0
383 / 281 / 31
Регистрация: 04.09.2009
Сообщений: 1,225
05.01.2014, 04:00 4
Цитата Сообщение от Kant Посмотреть сообщение
Сижу под Win 7.
Если бы пересели на *nix, то решение вашей проблемы:
Bash
1
cat * > file
Ну или на Си:
C
1
int main() { system("cat * > file"); }
А так мудрите
1
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.01.2014, 04:26 5
Цитата Сообщение от Kant Посмотреть сообщение
Чтение и запись с помощью С++ отпадает
Потоками, разумеется, лучше не пользоваться. Никаким "построчным" чтением тоже.

Используйте Memory Mapping (WinAPI) - открываете Src файл на чтение и "одним глотком" переписываете в Dst. Если файлы маленькие, то основное время уйдет не на копирование, а на сам поиск/открытие/закрытие. Если необходимо, добавляйте в Dst символ новой строки после каждого записанного файла.
1
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
05.01.2014, 04:43  [ТС] 6
Цитата Сообщение от alsav22 Посмотреть сообщение
Когда-то выяснял какими функциями быстрее всего работать с файлами. Получилось, что самые быстрые - это С-функции пстрочного чтения/записи: fgets(), fputs(). Файл нужно открывать в бинарном режиме, это убыстряет работу этих функций (почему - не знаю, но факт). Насколько знаю, работа с динамической памятью - это медленно, поэтому лучше использовать массив на стеке под размер строки (тем более, размер известен).
Написал вот такую штуку. Медленней чем мой код. Посмотри пожалуйста может что то не так сделал.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    FILE * pFileRead = _wfopen ( pathRead.c_str() , L"rb" );
    if(!pFileRead) return;
 
    FILE * pFileWrite = _wfopen ( pathAddWrite.c_str(), L"ab" );
    char buffer[80];
 
    while(!feof(pFileRead)) {
        if(fgets(buffer, 80, pFileRead) != 0)
            fputs(buffer, pFileWrite);
    }
 
    fputs("\0", pFileWrite);
 
    fclose (pFileRead);
    fclose (pFileWrite);
}
Добавлено через 1 минуту
Цитата Сообщение от gazlan Посмотреть сообщение
Потоками, разумеется, лучше не пользоваться. Никаким "построчным" чтением тоже.

Используйте Memory Mapping (WinAPI) - открываете Src файл на чтение и "одним глотком" переписываете в Dst. Если файлы маленькие, то основное время уйдет не на копирование, а на сам поиск/открытие/закрытие. Если необходимо, добавляйте в Dst символ новой строки после каждого записанного файла.
Читал об этом. Но на моем уровне задача неподъемная. Если бы показали маленький пример был бы благодарен!
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
05.01.2014, 05:29 7
Цитата Сообщение от Kant Посмотреть сообщение
Написал вот такую штуку. Медленней чем мой код.
Насчёт меделнней или быстрей ничего нового не скажу, что знал и пробовал - изложил. Забыл только сказать, что в Release нужно делать.
C++
1
2
while(fgets(buffer, 80, pFileRead)) 
       fputs(buffer, pFileWrite);
1
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.01.2014, 05:39 8
Цитата Сообщение от Kant Посмотреть сообщение
маленький пример
Эташ.
Вложения
Тип файла: 7z Joiner.7z (8.9 Кб, 90 просмотров)
1
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.01.2014, 05:42 9
Цитата Сообщение от alsav22 Посмотреть сообщение
убыстряет работу этих функций (почему - не знаю, но факт)
Нет затрат на трансляцию EOL.
1
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
05.01.2014, 06:07  [ТС] 10
Цитата Сообщение от gazlan Посмотреть сообщение
Эташ.
Ого! Вот что то такого и боялся )
0
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
05.01.2014, 06:16  [ТС] 11
Цитата Сообщение от alsav22 Посмотреть сообщение
Насчёт меделнней или быстрей ничего нового не скажу, что знал и пробовал - изложил. Забыл только сказать, что в Release нужно делать.
C++
1
2
while(fgets(buffer, 80, pFileRead)) 
       fputs(buffer, pFileWrite);
Угу. В Release запускал. С меня, правда, такой тестер ) Переключил на Релиз и прогнал пару раз. Измеряю время вот так:
C++
1
2
3
4
5
6
7
    DWORD start = GetTickCount();
    FindToPdnBase(L"D:\\Партии\\PDN", L".pdn", L"D:\\MegaBase.pdn");
    DWORD finish = GetTickCount();
    
    cout << "\tПрограмма управилась за "  << finish - start << "\n";
 
Надо бы саму функцию, но решил весь класс.
Зато с вашим советом память вообще не тратится )) И в среднем на 2-3 секунды медленней, что по сути ерунда. И
код короче намного ) Буду теперь только так юзать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void FindToPdnBase::read_and_write(const wstring &pathRead, const wstring &pathAddWrite) {
    FILE * pFileRead = _wfopen ( pathRead.c_str() , L"rb" );
    if(!pFileRead) return;
 
    FILE * pFileWrite = _wfopen ( pathAddWrite.c_str(), L"ab" );
    static char buffer[80];
 
    while(fgets(buffer, 80, pFileRead))
            fputs(buffer, pFileWrite);
 
    fputs("\0", pFileWrite);
 
    fclose (pFileRead);
    fclose (pFileWrite);
}
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
05.01.2014, 06:27 12
Я вот на таком коде пробую (в студии 10). В файле 1000000 строк, размер каждой - около 45 символов. Размер файла 46.7мгб.
Если построчно: Debug - 0.83, Release - 0.5.
Если блоком, размером в файл: Debug - 0.84, Release - 0.813.
Получается, что самое быстрое - построчно, и именно в Release (оптимизация там для построчного лучше сделана или что, не знаю. Оптимизация выставлена - максимальная скорость).
Кликните здесь для просмотра всего текста
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
include <iostream>
#include <string>
#include <ctime>
#include <fstream>
 
using namespace std;
 
const int N = 1000000; // количество строк в файле
const int L = 500;     // длина строки
 
void createfile() //создание файла для теста
{
    string str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
    ofstream fout("file1.txt");
    for (int i = 0; i < N; ++i)
    {
        fout << i + 1;
        fout << str << endl;
    }
    fout.close();
}
 
int main()
{
    //createfile(); //создание файла для теста
    
    clock_t t1 = clock();
    FILE *fin = fopen("file1.txt", "rb"); // в бинарном быстрее
    
    if (!fin) printf("Error!\n");
    else
    {
        FILE *fout = fopen("file2.txt", "wb");
        
        // построчно
      //begin...............................
        
        char str1[L] = {'\0'};       
        while (fgets(str1, L, fin)) 
                fputs(str1, fout);
      //end ...................................     
        
        // блоком, размером с размер файла
     //begin...............................
        
        /*fseek(fin, 0, SEEK_END); 
        int size = ftell(fin);
        char * buffer = (char*) malloc(size);
        
        rewind(fin);
        fread(buffer, 1, size, fin);
        fwrite(buffer, 1, size, fout);
        free(buffer);*/
     
     //end ...................................  
        
        fclose(fout);
        fclose(fin);
        
        clock_t t2 = clock();
        printf("%f\n", (t2 - t1 + .0) / CLOCKS_PER_SEC); // время отработки
    }
  
    system("pause");
    return 0;
}
0
3176 / 1935 / 312
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
05.01.2014, 06:46 13
Цитата Сообщение от Kant Посмотреть сообщение
такого и боялся
Там уже скомпилированная аппликация. Просто запустите ее на вашем наборе.
1
37 / 37 / 18
Регистрация: 15.05.2013
Сообщений: 236
05.01.2014, 13:12  [ТС] 14
Цитата Сообщение от gazlan Посмотреть сообщение
Там уже скомпилированная аппликация. Просто запустите ее на вашем наборе.
Спасибо! Но хотел получить что нибудь для понимания, а потом уже с наработанными деталями. Но все равно спасибо, код там не сложный некоторые функции погуглить.
0
05.01.2014, 13:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.01.2014, 13:12
Помогаю со студенческими работами здесь

Слить много контейнеров в один
здравствуйте, подскажите, что не так в коде, ибо не совсем правильно работает (мозг сносит уже от...

Один большой класс или много маленьких?
Здравствуйте. В программе есть N функций, которые необходимо выполнять друг за другом, но в...

Один длинный Regex или много маленьких?
Пытаюсь сделать мат-фильтр. Ничего кроме регекса к голову не пришло... Вопрос: искать одним...

Чтовыгоднее один большой сайт или много маленьких
Вот скажите новичку что выгоднее будет предположим один сайт раскрученный под много запросов и 300...

Проверка наличия трех текстовых файлов на диске и объединения их в один файл
Помогите плз с заданием. Создать два пакетных файла, реализующих следующие задачи: 1. Проверка...

Составить программу, считывающую информацию из текстовых файлов в один нетипизированный файл
Здравствуйте, хотелось бы попросить вашей помощи с одной, вроде бы не сложной, программкой. ...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru