Russian Qt Forum

Qt => Общие вопросы => Тема начата: bvn13 от Март 05, 2010, 09:52



Название: (почти БД) Как быстрее обработать большой файл?
Отправлено: bvn13 от Март 05, 2010, 09:52
Не совсем БД это, но теоретически, очень даже похоже.
Есть log-файл одной проги. Сейчас он занимает около 12 метров. В нем четко прослеживаются поля (как если бы это была таблица ДБФ, к примеру). формат - текстовый, русские буквы + англ.буквы.

Мне необходимо:
1) сделать удобный просмотрщик для него (т.е., например, в каждой строке в позиции 22 (string[22]) идет символ разделение на таблицы - как я это себе представляю. ДО этого символа - дата записи. ПОСЛЕ этого символа - служебное сообщение). мне нужно разделить весь лог на несколько (10) таблиц с фильтром по string[22]-символу (там число просто, кста, может быть и не один символ, а два, если число перевалит 10).
2) сделать возможность "слежки" за этим логом - нужно проверять, как давно появилась запись с определенным символом в позиции string[22]. если больше, чем определенное количество секунд (минут), то "поднимать тревогу" (тут пока рано говорить о видах тревоги, но, может быть, придется ;) )

Хочу попросить совета по первому пункту. Как это лучше организовать? я вчера набросал тестовый проект (в QTreeWidget пихаю все различные символы в позиции string[22] всего файла (это идет секунд 15). потом перебором (уже вторым, знаю, что не оптимизировано) по двойному щелчку на QTreeWidgetItem я начинаю поиск (цикл с условием на сравнение этого символа в 22 позиции) нужных мне строк, которые потом запихиваю в QTableWidget в две колонки: первая - ДО символа в 22 позиции, вторая - все, что после него). И вот эта операция занимает аж несколько минут, при котором прога подвисает (без потоков пока делал, просто проверить).

Подскажите, как лучше организовать все, чтобы прога была максимально portable? Я уже думал в сторону всяких там SQL-БД... но я пока с ними не особо работал. Может есть вариант без использвания их? Может есть вариант использования SQL-запроса к какой-нибудь QTableWidget? В общем, подскажите, куды копать лучше будет...

ЗЫ! ОС - Винда
ЗЗЫ! сам лог обновляется где-то 1 раз в 2-20(30) секунд... так что перечитывать его придется все равно, чтобы актуальность была.


Название: Re: (почти БД) Как быстрее обработать большой файл?
Отправлено: Igors от Март 05, 2010, 10:43
Не совсем БД это, но теоретически, очень даже похоже.
Есть log-файл одной проги. Сейчас он занимает около 12 метров.
12 метров - это по нынешним временам не объем (да и по вчерашним тоже). Где-то до 500 метров можно жить просто читая весь файл в память, не связываясь с БД

Хочу попросить совета по первому пункту. Как это лучше организовать? я вчера набросал тестовый проект (в QTreeWidget пихаю все различные символы в позиции string[22] всего файла (это идет секунд 15). потом перебором (уже вторым, знаю, что не оптимизировано) по двойному щелчку на QTreeWidgetItem я начинаю поиск (цикл с условием на сравнение этого символа в 22 позиции) нужных мне строк, которые потом запихиваю в QTableWidget в две колонки: первая - ДО символа в 22 позиции, вторая - все, что после него). И вот эта операция занимает аж несколько минут, при котором прога подвисает (без потоков пока делал, просто проверить).
Читаем все в 1 блок памяти (без QString), разбираем строки и "позицию 22", это должно занять до 5 секунд даже на слабеньком железе и без всяких потоков. Вот затем можно подумать как лучше/быстрее добавить это в UI. Данные я бы организовал так:

Код:
QVector <char> theLogData;  // содержимое файла скопированное в память

struct MyStr {
 int mBeg1;       // смещение первой суб-строки в theLogData
 int mBeg2;       // смещение второй суб-строки в theLogData
 int mEnd;        // смещение конца строки
 int mKey22;     // значение в "позиции 22"
};

QVector <MyStr> theStr;  // в результате разборок этот вектор заполнен
А строки получать в делегате, незачем их хранить



Название: Re: (почти БД) Как быстрее обработать большой файл?
Отправлено: bvn13 от Март 05, 2010, 11:11
Читаем все в 1 блок памяти (без QString), разбираем строки и "позицию 22", это должно занять до 5 секунд даже на слабеньком железе и без всяких потоков. Вот затем можно подумать как лучше/быстрее добавить это в UI. Данные я бы организовал так:

Код:
QVector <char> theLogData;  // содержимое файла скопированное в память
А строки получать в делегате, незачем их хранить

спасибо, чего-то я про вектор не вспомнил :)

а потом обрабатываеть простым циклом или же есть способ заюзать запрос какой-нибудь?


Название: Re: (почти БД) Как быстрее обработать большой файл?
Отправлено: dio от Март 05, 2010, 15:38
Предлагаю следующее решение:

1. Каждые 20 сек. парсить логфайл на предмет новых записей (не стоит каждый раз перечитывать файл сначала, следует запоминать номер последней считанной строки и в следующий раз читать с этой позиции), требуемую информацию выводить в файл формата csv. Это можно реализовать с помощью планировщика задач
  (например, стандартный виндовый, CRON, итд) и утилит обработки данных (AWK, LogParser).
2. А для чтения csv файла из приложения можно использовать, скажем, ODBC.


Название: Re: (почти БД) Как быстрее обработать большой файл?
Отправлено: Igors от Март 05, 2010, 16:11
а потом обрабатываеть простым циклом или же есть способ заюзать запрос какой-нибудь?
Не знаю что значит "обрабатывать". Если есть вектор theStr - то все данные уже на руках. Как перерисовать таблицу - точно не скажу, но добавлять строку за строкой не следует. Я бы смотрел в сторону data model, основанной на theLogData и theStr. Считал данные, сказал таблице setModel - готово.

Насчет "слежки" - имеет смысл полагать что данные доливаются в конец лога (append). Это можно проверить используя даты создания и модификации файла. Если это не так - ничего не попишешь, придется перечитать весь файл. Чтение "хвоста" такое же как и всего файла - надо только сначала сделать seek на хвост и resize для theLogData.