Russian Qt Forum
Сентябрь 30, 2024, 22:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: (почти БД) Как быстрее обработать большой файл?  (Прочитано 3577 раз)
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) секунд... так что перечитывать его придется все равно, чтобы актуальность была.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Март 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;  // в результате разборок этот вектор заполнен
А строки получать в делегате, незачем их хранить

Записан
bvn13
Гость
« Ответ #2 : Март 05, 2010, 11:11 »

Читаем все в 1 блок памяти (без QString), разбираем строки и "позицию 22", это должно занять до 5 секунд даже на слабеньком железе и без всяких потоков. Вот затем можно подумать как лучше/быстрее добавить это в UI. Данные я бы организовал так:

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

спасибо, чего-то я про вектор не вспомнил Улыбающийся

а потом обрабатываеть простым циклом или же есть способ заюзать запрос какой-нибудь?
Записан
dio
Гость
« Ответ #3 : Март 05, 2010, 15:38 »

Предлагаю следующее решение:

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

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Март 05, 2010, 16:11 »

а потом обрабатываеть простым циклом или же есть способ заюзать запрос какой-нибудь?
Не знаю что значит "обрабатывать". Если есть вектор theStr - то все данные уже на руках. Как перерисовать таблицу - точно не скажу, но добавлять строку за строкой не следует. Я бы смотрел в сторону data model, основанной на theLogData и theStr. Считал данные, сказал таблице setModel - готово.

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


Страница сгенерирована за 0.081 секунд. Запросов: 22.