Всем привет! Буду краток.
Появилась у меня в проекте задача наблюдать за изменениями файла(ов) на диске. Зная что в 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???Любые предположения, что бы это могло быть и как можно исправить. Способ "в лоб" - перезаписывать список наблюдения после каждого отловленного сигнала не предлагать, ибо знаю.