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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QFileSystemWatcher (bug?)  (Прочитано 8429 раз)
NKovalev64
Гость
« : Июль 13, 2014, 15:12 »


Всем привет! Буду краток.
Появилась у меня в проекте задача наблюдать за изменениями файла(ов) на диске. Зная что в Qt есть класс QFIleSystemWatcher, подумал что это будет легко, но не тут то было.
Я прекрасно понимаю что операция слежения за изменениями файловой системы - это очень платформозависимая вещь, и в целом написать такой класс (функционал) весьма сложно, именно из за тонкостей реализации на каждой платформе.
Что же получилось у меня? Сделал новый простой проект, для тестирования класса QFileSystemWatcher:
QFileSystemWatcher m_watcher - приватный член класса.
В конструкторе класса пишу следующее:
Код:
m_watcher = new QFileSystemWatcher(this);

connect(ui->pushButtonAddFiles, &QPushButton::clicked, [this](){
        QStringList paths = QFileDialog::getOpenFileNames(this);
        m_watcher->addPaths(paths);
});

connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &MainWindow::loggingFileChanges);

Функция loggingFileChanges (в которой в общем объект m_watcher никак не изменяется):
Код:
void MainWindow::loggingFileChanges(const QString &path)
{
    QFileInfo fileInfo(path);
    QDateTime lastModified =
            fileInfo.exists() ? fileInfo.lastModified() : QDateTime::currentDateTime();

    QString record = QString("[%1]\t%2\t%3 bytes")
            .arg(lastModified.toString(Qt::ISODate))
            .arg(path)
            .arg(fileInfo.size());

    ui->logBrowser->append(record);
}

Так вот, запустил я это дело на Win7x64 под msvc12x64 и под MinGW 4.8.2 - все работает отлично, добавляю файлы, изменяю их - m_watcher ловит все сигналы об изменении. Правда периодически славливает по 2 сигнала на 1 изменение, но как я прочитал на форумах QtProject - это глюк или даже фича win32Api, на котором сделана реализация ватчера для Windows. В общем этот баг меня не сильно напрягает и не о нем вопрос.
Веселье началось когда запустил тот же код на Linux:
Код:
Linux sw-virtual-machine 3.13.0-30-generic #55-Ubuntu SMP Fri Jul 4 21:40:53 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
Код собран g++:
Код:
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Что происходит?
1. Добавляю файл под наблюдение
2. Изменяю файл
3. ватчер ловит сигнал об изменении файла
4. Изменяю файл еще раз
5. Никакой реакции со стороны ватчера.
6. Проверяю m_watcher->files() - там пусто.
7. НепонимающийНепонимающийНепонимающий

Опытным путем установлено, что между пунктами 3 и 4, (скажем в пункте 3,14 Подмигивающий) файл, об изменении которого был пойман сигнал - удаляется из списка наблюдения объекта m_watcher, причем другие (не измененные файлы) в этом списки остаются, но, опять же - до первого изменения. WTF???

Любые предположения, что бы это могло быть и как можно исправить. Способ "в лоб" - перезаписывать список наблюдения после каждого отловленного сигнала не предлагать, ибо знаю.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #1 : Июль 13, 2014, 15:23 »

Вы тестовый проект в архиве выложили, а мы бы позапускали.
Возможно уже все исправлено в следующих версиях.
Записан
NKovalev64
Гость
« Ответ #2 : Июль 13, 2014, 15:29 »

Вы тестовый проект в архиве выложили, а мы бы позапускали.
Возможно уже все исправлено в следующих версиях.


https://github.com/DustOffRoad/BinaryFileWatcher

Забыл уточнить - Qt 5.3.1. Всегда стараюсь использовать только последние версии.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Июль 13, 2014, 15:45 »

А у меня все работает.
Версия тоже 5.3.1.
Записан
NKovalev64
Гость
« Ответ #4 : Июль 13, 2014, 15:54 »

А у меня все работает.
Версия тоже 5.3.1.


Хм. Удивительно, право же.
Тестировал на виртуалке и на обычной машине. Правда обе одинаковые - вышеозначенные Kubuntu 14.04

В любом случае - спасибо большое! Обнадежили. Буду искать в чем у меня причины такого поведения.
Записан
NKovalev64
Гость
« Ответ #5 : Июль 13, 2014, 23:00 »

А у меня все работает.
Версия тоже 5.3.1.


Я все же решительно не могу понять в чем тут загвоздка. Запустил на Ubuntu 14.04 - ватчер ловит 1 первый сигнал об изменении нормально, потом ловит второй и удаляет файл из списка наблюдения ватчера. Почему? Я всю голову сломал.

P.S.: Я нашел подтверждение своего подозрения: http://www.cyberforum.ru/qt/thread696674.html
« Последнее редактирование: Июль 13, 2014, 23:09 от NKovalev64 » Записан
Bepec
Гость
« Ответ #6 : Июль 13, 2014, 23:21 »

Покопайтесь в сырцах. Вдруг там ответ кроется Улыбающийся
Записан
NKovalev64
Гость
« Ответ #7 : Июль 14, 2014, 00:57 »

Покопайтесь в сырцах. Вдруг там ответ кроется Улыбающийся

Кажется ответ открылся. Дело в том, что текстовые редакторы (Kate например) - не просто записывают изменения в файл а перезаписывают его, удаляя перед этим оригинал. Из за того что файл удаляется, он отцепляется от ватчера. Если редактировать файл через nano такого не происходит.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #8 : Июль 14, 2014, 07:28 »

Дело в том, что текстовые редакторы (Kate например) - не просто записывают изменения в файл а перезаписывают его, удаляя перед этим оригинал.
Скорее всего не удаляет файл оригинал, а переименовывает его в .bak, а новый вариант сохранят под указанным именем.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Июль 14, 2014, 07:36 »

Поэтому нужно ещё следить за изменениями папки.
Записан

Qt 5.11/4.8.7 (X11/Win)
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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