Dear Friends
I am using QFileSystemWatcher for knowing when the file is modified from outside my application. I am seeing even if the file is modified from the application this is giving message that the file is modified. Can anyone tell whats going wrong in this..see the snippet below
[code]
QFile file(“/home/sdh/projects/opt.cfg”);
watcher = new QFileSystemWatcher(this);
connect(watcher,SIGNAL(fileChanged(const QString &)),this, SLOT(cfgFileModified(const QString &)));
watcher->addPath(file.fileName());
[\code]
Please tell me whats going wrong. I am modifying the file from my application then also its giving message. Thanks for any help. Thanks Sujan
Kind regards,
Sujan Dasmahapatra
Project Leader, Aero Group
CE - Aero Group
Tel +91 80 66470248
Mob
LM Wind Power Blades
Together we capture the wind to power a cleaner world
This e-mail and any attachments are confidential. If you are not the named or intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Any unauthorized disclosure, use or storage is prohibited and might be unlawful.
There is nothing going wrong here, thats how QFileSystemWatcher is
intended to work. If you don't want to be notified for changes you're
doing yourself you need to add code for that in your application.
Andreas
_______________________________________________
Interest mailing list
Inte...@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest
And this is of course the task for a SignalBlocker. I've done exactly
this (block QFileSystemWatcher) for a customer a couple of months ago,
and it really is the only solution.
I just put my SignalBlocker implementation on my blog:
http://www.fioniasoftware.dk/blog/?p=158
(Sorry for the plug but it was a bit long for a mail, and there might be
other interested in it.)
With this class you just do this:
{
SignalBlocker blocker(watcher);
modifyTheFile();
}
I hope this helps.
Bo Thorsen,
Fionia Software.
--
Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk
André
That only works as long as the detection of changes happens immediately,
that might not be the case all the time since it depends on which
backend QFSWatcher uses (there's a polling one). Usually I add a
modification-timestamp check to the system, i.e. store the
modification-time right after modifying the file and then compare when
the QFSWatcher triggers. This is of course not a 100% safe solution
(hashing the file would be even better) but in my experience good
enough.
Andreas
Kind regards,
Sujan Dasmahapatra
Project Leader, Aero Group
CE - Aero Group
LM Wind Power Blades
lmwindpower.com
Together we capture the wind to power a cleaner world
This e-mail and any attachments are confidential. If you are not the named or intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Any unauthorized disclosure, use or storage is prohibited and might be unlawful.
André
That's not a correct assumption. QFileSystemWatcher's job is to report
modifications. It doesn't care what made them. Filtering the changes
your application makes is your application's responsibility.
> With this class you just do this:
>
> {
> SignalBlocker blocker(watcher);
> modifyTheFile();
> }
It seems to me that there's a race condition here.
Unless you're taking steps to deliberately lock-out
other processes from modifying the file, then they
could slip in immediately before or after you modify
the file and you would never know they'd been there
because you have the signal blocked.
A later reply talks about hashing the file; if you
really want precision notification of modifications,
then that's the sort of thing you have to do *EVERY
TIME* the file watcher tells you a modification has
been made, even if you suspect that the modification
was your own. Either that, or lock-out other changers
while you make your change.
Atlant
-----Original Message-----
From: interest-bounces+aschmidt=dekarese...@qt-project.org [mailto:interest-bounces+aschmidt=dekarese...@qt-project.org] On Behalf Of André Somers
Sent: Thursday, January 12, 2012 03:27
To: inte...@qt-project.org
Subject: Re: [Interest] QFileSystemWatcher malfunctioning
André
Click https://www.mailcontrol.com/sr/!2Y+ytpCNNXTndxI!oX7UsdpzMR7Bo2KuJJ25aNl2Ia2ErDASQGKpjk4Jw0OJtPBO9sXebjFfhJ6aunJTqVygQ== to report this email as spam.
This e-mail and the information, including any attachments, it contains are intended to be a confidential communication only to the person or entity to whom it is addressed and may contain information that is privileged. If the reader of this message is not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender and destroy the original message.
Thank you.
Please consider the environment before printing this email.
True. But if you modify the file, you have a race condition anyway,
since you don't know if that was done before or after you do this. You
might not get the modified signal before you change the file contents.
If you're after a fool proof system, don't block the filewatcher and
read it after your own changes, and check that the contents hadn't been
changed before you do it. Or use a database.
Bo Thorsen,
Fionia Software.
--
Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk
Dear Thorsen
I need your help. I have implemented the SignalBlocker class in a new header file;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef SIGNALBLOCKER_H
#define SIGNALBLOCKER_H
/**
* Small helper class that blocks all signals from an object for the lifetime of this object.
* it is safe against deletion of the object before deletion of this.
*
* This class was written by Bo Thorsen of Fionia Software <b...@fioniasoftware.dk>.
* The code is in the public domain.
*/
class SignalBlocker {
public:
explicit SignalBlocker(QObject* object) : mObject(object) {
mWasBlocked = object->signalsBlocked();
object->blockSignals(true);
}
~SignalBlocker() {
if (mObject && !mWasBlocked)
mObject->blockSignals(false);
}
private:
// Disabled
SignalBlocker(const SignalBlocker&);
SignalBlocker& operator=(const SignalBlocker&);
QPointer<QObject> mObject;
bool mWasBlocked;
};
#endif // SIGNALBLOCKER_H
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
Now I have 2 .cpp files. One is plotgraphs.cpp and other is mainwindow.cpp
So I want to block the signal at some function in mainwindow.cpp
And my QFileSystemWatcher object is initialized and connected in plotgraphs.cpp file. Like below.
//plotgraphs.cpp
QFileSystemWatcher *watcher;
/////////////////////////////////////
PlotGraphsDlg::PlotGraphsDlg(MainWindow *parent)
{
watcher = new QFileSystemWatcher(this);
connect(watcher,SIGNAL(fileChanged(const QString &)),this, SLOT(cfgFileModified(const QString &)));
}
/////////////////////////////////////
And in mainwindow at some function I am modifying the file. So in that function in the beginning I am writing this
/////////////////////////////////////////
void MainWindow::saveCFG()
{
if(!plotgraphsdlg)
return;
SignalBlocker blocker(plotgraphsdlg->watcher); //blocking the signal
QString update;
QFile file(filename);
if(!file.exists())
return;
if(!file.open(QIODevice::WriteOnly))
qWarning("Cannot Open file % s", filename);
QTextStream out(&file);
out << update; //This is updating the file.....
}
/////////////////////////////////////////
But after updating I am still getting the message that the file is updated. The signal is not blocked. Please tell me whats going wrong in this. Thanks in advance for your help.
Kind regards,
Sujan Dasmahapatra
Project Leader, Aero Group
CE - Aero Group
Tel +91 80 66470248
Mob
LM Wind Power Blades
Together we capture the wind to power a cleaner world
This e-mail and any attachments are confidential. If you are not the named or intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Any unauthorized disclosure, use or storage is prohibited and might be unlawful.
-----Original Message-----
From: interest-bounces+sdh=lmwindp...@qt-project.org [mailto:interest-bounces+sdh=lmwindp...@qt-project.org] On Behalf Of Bo Thorsen
Sent: Thursday, January 12, 2012 1:45 PM
To: inte...@qt-project.org
Subject: Re: [Interest] QFileSystemWatcher malfunctioning
Most probably the watcher notices the change asynchronously, i.e. after
your function has ended and the signal blocker has been deleted. You
should be able to verify that either using a debugger or by printing
some timestamps to see when the function is exited and when the slot
connected to the signal is received
Andreas
That is a bit surprising to me, since I actually used it exactly for
blocking a file watcher, and that worked fine. Perhaps a flush is
necessary on the stream.
Bo Thorsen,
Fionia Software.
--
Expert Qt and C++ developer for hire
Contact me if you need expert Qt help
http://www.fioniasoftware.dk
Well, it depends on how the Filewatcher does the watching, which depends
on what the OS provides for watching files and wether its
enabled/disabled. QFSWatcher uses a Polling-Backend in case it cannot
use some native notification system and that one surely is asynchronous.
Andreas
Am 02.02.2012 um 15:49 schrieb Sujan Dasmahapatra <sujan.das...@gmail.com>:
> May Thorson you're right, I'll do a flush on the stream and see. Also I'll follow Andreas suggestion check it by debugging. It should work. Thanks for your valuable suggestions.
No. That cannot possibly work. Even if the file is being polled (that is handled *synchronously* by the Qt event queue) imagine if the poll interval was one minute! Your method would have long returned before (and hence the signal blocker destroyed) before the Qt event queue would be informed either via a QTimer based polling (synchronous) or (asynchronously) via some OS event.
In any case the Qt event queue can only handle such an event *after* your method has returned (and have the QFileWatcher emit its signal): no Qt event interrupts your method execution, so the QFileWatcher would not emit any signals while your method is being executed anyway!
So I cannot imagine how that could have worked with Bo's solution in the first place - unless off course we are talking about multiple threads, but even then chances are that your method (where you try to block the signal from QFileWatcher) would finish *before* the OS gets a chance to notify the application and you would *still* get the signal (at some random time in the future) later on.
So unless you write some application-specific values (an encrypted signature for example which only your process can create, in the extreme case) into the file I don't see how you could detect whether it was your or some other process that modified the file last!
Cheers, Oliver
Its been a while since I looked at the insides on linux.
Scott
-----Original Message-----
From: interest-bounces+scott.bloom=onshor...@qt-project.org
[mailto:interest-bounces+scott.bloom=onshor...@qt-project.org] On
Behalf Of Till Oliver Knoll
Sent: Thursday, February 02, 2012 3:20 PM
To: inte...@qt-project.org
Subject: Re: [Interest] QFileSystemWatcher malfunctioning
All engines run in a separate thread and some of the engines have
multiple threads themselves again (win32 and dnotify) as far as I can
see from a quick grep.
However these threads could be delivering their signals directly
instead of delivering them through the event-queue, so there is actually
a way that the blocker really blocks signals.
But if the used backend is actually not triggered by the OS directly
when a filesystem change happens, i.e. if it takes a few ms for the OS
to notify the watcher (and thats definetly the case for the polling
backend) then signal blocking will not work.
Andreas
But it does take the event loop of the connected slots thread to be
running...
Scott
-----Original Message-----
From: interest-bounces+scott.bloom=onshor...@qt-project.org
[mailto:interest-bounces+scott.bloom=onshor...@qt-project.org] On
Behalf Of Andreas Pakulat
Sent: Thursday, February 02, 2012 3:54 PM
To: inte...@qt-project.org
Subject: Re: [Interest] QFileSystemWatcher malfunctioning
Yes, no, maybe. I didn’t write SignalBlocker…
As has been stated, keep a MD5 of the file after you write it, and ignore the file change notification if it hasn’t changed..
Am 03.02.2012 um 01:04 schrieb "Scott Aron Bloom" <Scott...@onshorecs.com>:
> I have found with windows at least, its instantaneous. Essentially it
> sets up a blocking win32 call, that gets release and emits the signal...
>
> But it does take the event loop of the connected slots thread to be
> running...
... and the later is exactly my point: the underlying implementation can be threaded ("asynchronous") or polling - but in the end it goes through the Qt event queue, and if *your* code is not multi-threaded then there is no point in blocking the signals of QFileWatcher, since the signal would get delivered only *after* your method returns to the Qt event queue anyway (and at that point the mentioned instance of the "signal blocker" would have gone, not blocking anything anymore).
But even if the application code itself was multi-threaded there is no *guarantee* when the OS would actually inform your application. "Instantaneously" might not be fast enough: depending on how fast your method is terminating you might indeed successfully block the signal in 99.9% of all cases - making you wonder why in the other 0.1% your code still seems to think that another process had modified the file, when in fact it was *your* process.
And that off course still does not take into account that on some other platforms the underlying implementation might be polling, and that the polling intervall X might just be slightly larger than the time Y it takes your method to execute (and hence the signal blocker would "live"). And again that would leave you wondering "But my code works on Windows (by chance), but not on Foo OS!"
So if your requirement would be: "For the lifetime of that *method* I don't want to get informed when *I* change that file" then the signal blocker approach would work (taking any possible race conditions out of the equation for now).
For all other scenarios one has to apply application-specific measures, such as some MD5 checksum which has been mentioned several times by now (possibly together with some "file-locking mechanisms" which make the story even more interesting when we talk about files located on network-mapped drives - did I hear "cloud services" just now? ;))
Cheers, Oliver