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

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

Восстановить пароль Регистрация
 
Kant
 Аватар для Kant
24 / 24 / 8
Регистрация: 15.05.2013
Сообщений: 213
05.01.2014, 03:03     Есть очень много маленьких текстовых файлов необходимо слить в один файл #1
Очень много маленьких файлов размером от 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);
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.01.2014, 03:03     Есть очень много маленьких текстовых файлов необходимо слить в один файл
Посмотрите здесь:

C++ Объединить несколько файлов в один файл, а потом добавлять туда еще файлы
C++ Проблемка с скачиванием не маленьких файлов в цикле
C++ Как определить, есть ли файл на диске. Проверка двух файлов
Слить один два файла в один C++
Нужен листинг на С++ (даны два вектора, упорядоченные по возрастанию. Слить их в один вектор, так чтобы сохранилась упорядоченность) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.01.2014, 03:38     Есть очень много маленьких текстовых файлов необходимо слить в один файл #2
Когда-то выяснял какими функциями быстрее всего работать с файлами. Получилось, что самые быстрые - это С-функции пстрочного чтения/записи: fgets(), fputs(). Файл нужно открывать в бинарном режиме, это убыстряет работу этих функций (почему - не знаю, но факт). Насколько знаю, работа с динамической памятью - это медленно, поэтому лучше использовать массив на стеке под размер строки (тем более, размер известен).
Kant
 Аватар для Kant
24 / 24 / 8
Регистрация: 15.05.2013
Сообщений: 213
05.01.2014, 03:41  [ТС]     Есть очень много маленьких текстовых файлов необходимо слить в один файл #3
Цитата Сообщение от alsav22 Посмотреть сообщение
Когда-то выяснял какими функциями быстрее всего работать с файлами. Получилось, что самые быстрые - это С-функции пстрочного чтения/записи: fgets(), fputs(). Файл нужно открывать в бинарном режиме, это убыстряет работу этих функций (почему - не знаю, но факт). Насколько знаю, работа с динамической памятью - это медленно, поэтому лучше использовать массив на стеке под размер строки (тем более, размер известен).
Спасибо. Сейчас попробую.
gromo
 Аватар для gromo
366 / 265 / 24
Регистрация: 04.09.2009
Сообщений: 1,214
05.01.2014, 04:00     Есть очень много маленьких текстовых файлов необходимо слить в один файл #4
Цитата Сообщение от Kant Посмотреть сообщение
Сижу под Win 7.
Если бы пересели на *nix, то решение вашей проблемы:
Bash
1
cat * > file
Ну или на Си:
C
1
int main() { system("cat * > file"); }
А так мудрите
gazlan
2867 / 1815 / 272
Регистрация: 27.08.2010
Сообщений: 4,919
Записей в блоге: 1
05.01.2014, 04:26     Есть очень много маленьких текстовых файлов необходимо слить в один файл #5
Цитата Сообщение от Kant Посмотреть сообщение
Чтение и запись с помощью С++ отпадает
Потоками, разумеется, лучше не пользоваться. Никаким "построчным" чтением тоже.

Используйте Memory Mapping (WinAPI) - открываете Src файл на чтение и "одним глотком" переписываете в Dst. Если файлы маленькие, то основное время уйдет не на копирование, а на сам поиск/открытие/закрытие. Если необходимо, добавляйте в Dst символ новой строки после каждого записанного файла.
Kant
 Аватар для Kant
24 / 24 / 8
Регистрация: 15.05.2013
Сообщений: 213
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 символ новой строки после каждого записанного файла.
Читал об этом. Но на моем уровне задача неподъемная. Если бы показали маленький пример был бы благодарен!
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
05.01.2014, 05:29     Есть очень много маленьких текстовых файлов необходимо слить в один файл #7
Цитата Сообщение от Kant Посмотреть сообщение
Написал вот такую штуку. Медленней чем мой код.
Насчёт меделнней или быстрей ничего нового не скажу, что знал и пробовал - изложил. Забыл только сказать, что в Release нужно делать.
C++
1
2
while(fgets(buffer, 80, pFileRead)) 
       fputs(buffer, pFileWrite);
gazlan
2867 / 1815 / 272
Регистрация: 27.08.2010
Сообщений: 4,919
Записей в блоге: 1
05.01.2014, 05:39     Есть очень много маленьких текстовых файлов необходимо слить в один файл #8
Цитата Сообщение от Kant Посмотреть сообщение
маленький пример
Эташ.
Вложения
Тип файла: 7z Joiner.7z (8.9 Кб, 48 просмотров)
gazlan
2867 / 1815 / 272
Регистрация: 27.08.2010
Сообщений: 4,919
Записей в блоге: 1
05.01.2014, 05:42     Есть очень много маленьких текстовых файлов необходимо слить в один файл #9
Цитата Сообщение от alsav22 Посмотреть сообщение
убыстряет работу этих функций (почему - не знаю, но факт)
Нет затрат на трансляцию EOL.
Kant
 Аватар для Kant
24 / 24 / 8
Регистрация: 15.05.2013
Сообщений: 213
05.01.2014, 06:07  [ТС]     Есть очень много маленьких текстовых файлов необходимо слить в один файл #10
Цитата Сообщение от gazlan Посмотреть сообщение
Эташ.
Ого! Вот что то такого и боялся )
Kant
 Аватар для Kant
24 / 24 / 8
Регистрация: 15.05.2013
Сообщений: 213
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);
}
alsav22
5282 / 4801 / 442
Регистрация: 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;
}
gazlan
2867 / 1815 / 272
Регистрация: 27.08.2010
Сообщений: 4,919
Записей в блоге: 1
05.01.2014, 06:46     Есть очень много маленьких текстовых файлов необходимо слить в один файл #13
Цитата Сообщение от Kant Посмотреть сообщение
такого и боялся
Там уже скомпилированная аппликация. Просто запустите ее на вашем наборе.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.01.2014, 13:12     Есть очень много маленьких текстовых файлов необходимо слить в один файл
Еще ссылки по теме:

Сравнить содержание двоих текстовых файлов и вывести на экран номера строк в каких есть отличия C++
Слить несколько txt-файлов в один C++
Разделить файл txt на несколько равных маленьких файлов C++

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

Или воспользуйтесь поиском по форуму:
Kant
 Аватар для Kant
24 / 24 / 8
Регистрация: 15.05.2013
Сообщений: 213
05.01.2014, 13:12  [ТС]     Есть очень много маленьких текстовых файлов необходимо слить в один файл #14
Цитата Сообщение от gazlan Посмотреть сообщение
Там уже скомпилированная аппликация. Просто запустите ее на вашем наборе.
Спасибо! Но хотел получить что нибудь для понимания, а потом уже с наработанными деталями. Но все равно спасибо, код там не сложный некоторые функции погуглить.
Yandex
Объявления
05.01.2014, 13:12     Есть очень много маленьких текстовых файлов необходимо слить в один файл
Ответ Создать тему
Опции темы

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