Russian Qt Forum

Qt => Общие вопросы => Тема начата: NKovalev64 от Июль 13, 2014, 15:12



Название: QFileSystemWatcher (bug?)
Отправлено: 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???

Любые предположения, что бы это могло быть и как можно исправить. Способ "в лоб" - перезаписывать список наблюдения после каждого отловленного сигнала не предлагать, ибо знаю.


Название: Re: QFileSystemWatcher (bug?)
Отправлено: Old от Июль 13, 2014, 15:23
Вы тестовый проект в архиве выложили, а мы бы позапускали.
Возможно уже все исправлено в следующих версиях.


Название: Re: QFileSystemWatcher (bug?)
Отправлено: NKovalev64 от Июль 13, 2014, 15:29
Вы тестовый проект в архиве выложили, а мы бы позапускали.
Возможно уже все исправлено в следующих версиях.


https://github.com/DustOffRoad/BinaryFileWatcher

Забыл уточнить - Qt 5.3.1. Всегда стараюсь использовать только последние версии.


Название: Re: QFileSystemWatcher (bug?)
Отправлено: Old от Июль 13, 2014, 15:45
А у меня все работает.
Версия тоже 5.3.1.


Название: Re: QFileSystemWatcher (bug?)
Отправлено: NKovalev64 от Июль 13, 2014, 15:54
А у меня все работает.
Версия тоже 5.3.1.


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

В любом случае - спасибо большое! Обнадежили. Буду искать в чем у меня причины такого поведения.


Название: Re: QFileSystemWatcher (bug?)
Отправлено: NKovalev64 от Июль 13, 2014, 23:00
А у меня все работает.
Версия тоже 5.3.1.


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

P.S.: Я нашел подтверждение своего подозрения: http://www.cyberforum.ru/qt/thread696674.html


Название: Re: QFileSystemWatcher (bug?)
Отправлено: Bepec от Июль 13, 2014, 23:21
Покопайтесь в сырцах. Вдруг там ответ кроется :)


Название: Re: QFileSystemWatcher (bug?)
Отправлено: NKovalev64 от Июль 14, 2014, 00:57
Покопайтесь в сырцах. Вдруг там ответ кроется :)

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


Название: Re: QFileSystemWatcher (bug?)
Отправлено: Old от Июль 14, 2014, 07:28
Дело в том, что текстовые редакторы (Kate например) - не просто записывают изменения в файл а перезаписывают его, удаляя перед этим оригинал.
Скорее всего не удаляет файл оригинал, а переименовывает его в .bak, а новый вариант сохранят под указанным именем.


Название: Re: QFileSystemWatcher (bug?)
Отправлено: GreatSnake от Июль 14, 2014, 07:36
Поэтому нужно ещё следить за изменениями папки.