![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() |
Aleksei |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
задача открыть лог файл и найти в нём строку, выдать сообщение. Так как лог файл обновляется постоянно, то я буду по таймеру запускать поиск. Файл можно открыть только для чтения.
Товарищ FireBlack подсказал: "читаете его кусками и ищете искомую запись. Если, как Вы говорите, это большой лог файл (который только дополняется), то имеет смысл запоминать последнюю позицию и при следующем чтении файла начинать с нее." Но как это сделать я так и не понял, как работать с qt документацией? примеров не нашёл. Читаю книгу ООП Лафоре. так как не знаю как пользоваться этой подсказкой, пока придумал такую реализацию: - открою файл для чтения, сделаю поиск строки, выдаст сообщение если найдёт, посчитаю кол-во строк в файле, запомню в переменной номер последней строки, закрою файл. - по таймеру открою опять файл, из переменной возьму последнюю строку +1 и с этой строки буду опять искать, что бы не искать заново по всему файлу. ещё можно сделать проверку перед запуском поиска изменился ли файл, либо по его размеру, либо опять же по кол-ву строк определять. Если файл не изменился выдать предупреждение, что возможно повисла программа которая пишет в лог файл. смущает что лог файл большой и очень много строк будет, наверно мой способ будет медленный. подскажите как сделать правильней. |
|
|
![]() |
Trisch |
![]()
Сообщение
#2
|
![]() Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 379 Регистрация: 30.1.2012 Из: Запорожье Пользователь №: 3169 Спасибо сказали: 24 раз(а) Репутация: ![]() ![]() ![]() |
В принципе, алгоритм верный.
Для открытия файла и поиска строки понадобятся такие библиотеки QFile, QTextStream, QIODevice. Для того чтобы узнать был ли изменен файл можно воспользоваться библиотекой QFileInfo. |
|
|
lanz |
![]()
Сообщение
#3
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата запомню в переменной номер последней строки Лучше запоминайте позицию в файле, потом сделаете seek(товарищ FireBlack все верно говорит) А как найти строку с номером, не перечитывая файл с начала я даже не знаю. Цитата Но как это сделать я так и не понял, как работать с qt документацией? примеров не нашёл. Читайте detailed description класса, который хотите использовать, там обычно есть пример использования. Цитата либо по его размеру Еще лучше, запоминайте размер, и если он изменился, делайте seek на размер + 1. Тогда и позицию не надо будет хранить. Цитата смущает что лог файл большой и очень много строк будет, наверно мой способ будет медленный. Пусть не смущает. Пока не попробуете, не узнаете и никто вам не скажет ![]() |
|
|
Aleksei |
![]()
Сообщение
#4
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Цитата запомню в переменной номер последней строки Лучше запоминайте позицию в файле, потом сделаете seek(товарищ FireBlack все верно говорит) А как найти строку с номером, не перечитывая файл с начала я даже не знаю. Как запомнить позицию? хм не знаю, если даже прога и перечитает файл сначала, то поиск будет идти только с новых строк. В detailed description: Sequential devices don't support seeking to arbitrary positions. The data must be read in one pass. The functions pos() and size() don't work for sequential devices. QTcpSocket and QProcess are examples of sequential devices. Гугл перевод: Последовательные устройства не поддерживает поиск в произвольные положения. Данные должны быть считаны за один проход. Функции pos() и size() не работают для последовательных устройств. QTcpSocket и QProcess примеры последовательных устройств. Получается считывает тоже весь файл? вроде так: buffer.open(QIODevice::WriteOnly); buffer.seek(3); начнет после 3 символа. а как в pos() передать последнюю позицию (конец файла)? |
|
|
Aleksei |
![]()
Сообщение
#5
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
разобрался с проверкой изменения файла, конечно потом будет по таймеру но пока по клику на кнопку:
|
|
|
lanz |
![]()
Сообщение
#6
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата Получается считывает тоже весь файл? Нет, файл это не последовательное устройство. Цитата Как запомнить позицию? qint64 pos = file.size(); Цитата хм не знаю, если даже прога и перечитает файл сначала, то поиск будет идти только с новых строк. Это почему это? Цитата buffer.open(QIODevice::WriteOnly); Открыть файл только для записи. Нужно для чтения. Цитата а как в pos() передать последнюю позицию (конец файла)? file.seek(pos) |
|
|
Aleksei |
![]()
Сообщение
#7
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Aleksei |
![]()
Сообщение
#8
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
изучаю дальше и немного добавляю полезность в свою программу.
теперь ищу информацию как сделать поиск в файле. вопрос: буду делать поиск введённого слова в lineEdit есть ли разница если искать число а не текст. вообще программа задумывается как поиск числа 500 в файле, если есть выдать сообщение. |
|
|
lanz |
![]()
Сообщение
#9
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата теперь ищу информацию как сделать поиск в файле. Оберните файл в QTextStream, читайте readLine, запоминайте позицию, делайте seek, так же как и с файлом. Цитата вопрос: буду делать поиск введённого слова в lineEdit есть ли разница если искать число а не текст. Если файл бинарный, тогда в нем не получится искать текст, только числа, если текстовый, то наоборот. |
|
|
Aleksei |
![]()
Сообщение
#10
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Если файл бинарный, тогда в нем не получится искать текст, только числа, если текстовый, то наоборот. можно по подробней? файл текстовый (*.txt), ошибка будет выглядеть примерно так "дата время error = 500 а=1-2-3" хочу искать "500", может понадобится поиск и других ошибок по этому делаю через поля ввода. |
|
|
lanz |
![]()
Сообщение
#11
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата можно по подробней? Если файл текстовый, то число это просто набор символов 5, 0 и 0 поэтому и искать надо строку "500" А если файл бинарный, то число это набор байт 0x01 0xf4, причем как количество байт в записи числа, так и их порядок могут быть разные и это надо учитывать при чтении. Если быть совсем занудой, можно сказать что текстовый файл тоже бинарный, просто каждый его байт(или группа байт в случае юникода) представляет собой один символ. Искать примерно так:
Единственно о чем помнить, сохранять позицию только в конце строки (где есть перевод строки), потому что если сначала считаете файл "дата время error = 5" А потом продолжите поиск с 0 "00 а=1-2-3", то ничего не найдется. |
|
|
Aleksei |
![]()
Сообщение
#12
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
сделал пока поиск без позиций
всё ли логично и правильно? теперь буду пробовать с позициями. |
|
|
Aleksei |
![]()
Сообщение
#13
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
не пойму, что случилось, только что искал как надо.
стал пробовать с позициями потом строки с позициями закоментил, пробую просто поиск из предыдущего поста и он не работает. |
|
|
Aleksei |
![]()
Сообщение
#14
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
поиск работает не верно ищет только в последней строке.
|
|
|
lanz |
![]()
Сообщение
#15
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Казнить нельзя помиловать
![]() |
|
|
Aleksei |
![]()
Сообщение
#16
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
решил по другому сделать прогу.
поиск так и не заработал, ищет только в последней строке файла. решил пока разобраться с таймером для теста сделал так:
вроде всё работает, но при запуске QT в проблемах пишет: FTH: (4800): *** Fault tolerant heap shim applied to current process. This is usually due to previous crashes. *** что не так? |
|
|
Aleksei |
![]()
Сообщение
#17
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
пробовал оставить одну кнопку с выводом сообщения в статус бар, такая же ошибка.
упростил ![]()
|
|
|
Aleksei |
![]()
Сообщение
#18
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
сегодня этой ошибки уже нет.
добавил виджет QProgressBar, как сделать чтобы то время которое светится текст в ui->statusBar->showMessage("Нажата кнопка старт",2000); отображалось в QProgressBar. |
|
|
lanz |
![]()
Сообщение
#19
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
http://qt-project.org/doc/qt-4.8/qprogress...tml#format-prop
Если я все правильно понял. |
|
|
Aleksei |
![]()
Сообщение
#20
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
http://qt-project.org/doc/qt-4.8/qprogress...tml#format-prop Если я все правильно понял. спасибо но я не понял как этим воспользоватся. в принципе в моей программе ProgressBar будет заполнятся при поиске. Нужно с начало с поиском разобраться. |
|
|
Aleksei |
![]()
Сообщение
#21
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Переделал.
Поиск заработал, выводит строку в которой нашёл. Но если в тексте 400 или 40000, а я ищу 4 или 40 то он находит эту строку, как задать что бы правильно работало? Также если в тексте несколько строк с нужным текстом, то он отображает только последнюю, как тут быть? |
|
|
lanz |
![]()
Сообщение
#22
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Цитата Но если в тексте 400 или 40000, а я ищу 4 или 40 то он находит эту строку, как задать что бы правильно работало? Используйте регулярные выражения: http://qt-project.org/doc/qt-4.8/qregexp.html Цитата Также если в тексте несколько строк с нужным текстом, то он отображает только последнюю, как тут быть? Но находит все, просто
заменяет весь текст на каждую следующую найденную строку используйте append http://doc.qt.io/qt-5/qtextedit.html#append |
|
|
Aleksei |
![]()
Сообщение
#23
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
не могу найти как сделать что бы выводил (сверял) именно то число которое ввёл пользователь.
если ограничить {3} тремя символами, то это будет неправильно, ведь пользователь может захотеть искать и двухзначное число. QRegExp rx("[0-9]{1,4}"); результат решил выводить через List, теперь не затирает. ui->listWidget->addItem(rx.cap(0)); |
|
|
Aleksei |
![]()
Сообщение
#24
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
идея:
1) Можно найти длину строки вводимой в поиск и передать длину в QRegExp rx или 2) Проверить в найденном элементе, является ли следующий символ пробел (пустой). Как в посимвольном поиске сдвигают каретку на шаг. Можно ли тут так использовать. И какой из вариантов лучше? Сообщение отредактировал Aleksei - 1.3.2015, 9:40 |
|
|
lanz |
![]()
Сообщение
#25
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Зачем так сложно? Используйте последовательность \b
http://www.regular-expressions.info/wordboundaries.html |
|
|
Aleksei |
![]()
Сообщение
#26
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Зачем так сложно? Используйте последовательность \b http://www.regular-expressions.info/wordboundaries.html QRegExp rx (ui->lineEdit->text()+"\\b"); так? вроде работает. только в результат выдаёт то число, что мы искали, а мне нужно строку в которой нашли. Сообщение отредактировал Aleksei - 2.3.2015, 15:58 |
|
|
lanz |
![]()
Сообщение
#27
|
![]() Старейший участник ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 690 Регистрация: 28.12.2012 Пользователь №: 3660 Спасибо сказали: 113 раз(а) Репутация: ![]() ![]() ![]() |
Что то вроде:
Еще можно маркеры начала/конца добавить по вкусу или \n |
|
|
Aleksei |
![]()
Сообщение
#28
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
lanz, с тобой можно пообщаться? skype или icq
|
|
|
Aleksei |
![]()
Сообщение
#29
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
нашёл как сделать по другому
так как я считываю весь файл .*\\b500\\b.* выдаёт весь файл всё сразу. или лучше считывать построчно? что будет быстрей и менее нагружать комп? Сообщение отредактировал Aleksei - 3.3.2015, 1:04 |
|
|
Aleksei |
![]()
Сообщение
#30
|
Студент ![]() Группа: Участник Сообщений: 23 Регистрация: 3.9.2014 Пользователь №: 4219 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
рабочий поиск без позиций
|
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 10.7.2025, 11:16 |