C++ Qt QFileSystemWatcher file upload double -


i having issues file being uploaded twice server.

i using qfilesystemwatcher class c++ qt on windows xp send file when folder changes files small (1-12kb).

the application sends files scanning folder whenever changes (on directorychanged signal), loop through files , send 1 need. server responds xml file returned same folder application processes it.

apparently what’s happening on systems there 2 fast directorychanged signals @ same time , there 2 fast file uploads happening.

the server running apache , php, , there’s simple mutex in place on php side, wanted root of problem seems on qt side. i'm open using class, library or straight c++.

here code, stripped irrelevant content:

this->w = new qfilesystemwatcher(); this->w->addpath("c:/posera/maitred/data/int");  qstringlist directorylist = w->directories(); q_foreach(qstring directory, directorylist) {     qdebug() << "watching main directory name: " << directory << endl; }  directorywatcher* dw = new directorywatcher;  qobject::connect( this->w, signal(directorychanged(const qstring&)),                   dw, slot(directorychanged(const qstring&))); 

and directorywatcher.cpp:

directorywatcher::directorywatcher(qwidget* parent) : qwidget(parent) {     locksend = false; }  void directorywatcher::directorychanged(const qstring& str) {     directorylastchanged = str;      qbytearray bytearray = str.toutf8();     const char* cstring = bytearray.constdata();      sendchangedfiles(cstring); }  void directorywatcher::sendchangedfiles(const char* path) {     dir *dir;     struct dirent *ent;     if ((dir = opendir (path)) != null)     {         qstring str;          while ((ent = readdir (dir)) != null)         {             str = qstring("%1/%2").arg(path, ent->d_name);              qfileinfo info(str);              if (locksend == false &&                (info.completesuffix() == "xml" || info.completesuffix() == "xml") &&                (info.basename() != "") &&                (!info.basename().startswith("redm")) &&                (!info.basename().startswith("reft")))             {                 // reset counter.                 this->resendcounter = 0;                  sendfileandaccept(str.toutf8().constdata());             }         }         closedir (dir);     }     else     {         qdebug() << "could not open directory" << endl;     } }  class qnetworkrequest; class qnetworkreply;  void directorywatcher::sendfileandaccept(const char* path) {     // increment resend counter     this->resendcounter++;      qfileinfo fileinfo(path);      qnetworkaccessmanager * mgr = new qnetworkaccessmanager(this);     connect(mgr,signal(finished(qnetworkreply*)),             this,slot(saveresponse(qnetworkreply*)));     connect(mgr,signal(finished(qnetworkreply*)),             mgr,slot(deletelater())); // @todo delete later      qhttpmultipart *multipart = new qhttpmultipart(qhttpmultipart::formdatatype);      qhttppart filepart;     filepart.setheader(qnetworkrequest::contenttypeheader, qvariant("text/xml")); // @todo test     filepart.setheader(qnetworkrequest::contentdispositionheader, qvariant("form-data; name=\"somefile\"; filename=\"" + fileinfo.basename() + ".xml\""));      currentfilesent = fileinfo.basename();      qfile *file = new qfile(path);     file->open(qiodevice::readonly);     filepart.setbodydevice(file);     file->setparent(multipart); // cannot delete file now, delete multipart      multipart->append(filepart);      // post request     qnetworkreply *reply = mgr->post(qnetworkrequest(qurl(xxxxxx)), multipart);      multipart->setparent(reply); // delete multipart reply      // lock     locksend = true; }  void directorywatcher::saveresponse(qnetworkreply *rep) {      // response     qbytearray bts = rep->readall();     qstring str(bts);      // compute new path     qstring partname = currentfilesent.mid(1, currentfilesent.length());     qstring newpath = qstring("%1/a%2.xml").arg(directorylastchanged, partname);      qdebug() << "new path: " << newpath << endl;      switch (rep->error()) {         case qnetworkreply::noerror: {             qdebug() << "no error" << endl;              // save response file.              qfile file(newpath);             file.open(qiodevice::writeonly | qiodevice::text);             qtextstream out(&file);             out << str;              file.close();              break;         }         default:  //        case qnetworkreply::timeouterror : //        case qnetworkreply::hostnotfounderror :             qdebug() << "network reply error" << endl;             // resend file if counter < 10             if (this->resendcounter < 5) {                  // delay n sec                 qtime dietime = qtime::currenttime().addsecs(1);                 while( qtime::currenttime() < dietime )                     qcoreapplication::processevents(qeventloop::allevents, 100);                  sendfileandaccept(this->lastpathsent.tostdstring().c_str());             } else {                  // after 10 attempts, we're sure network down                 // save file somewhere , generate default 1 prevent timeouts.                  qdebug() << "saving file later..." << endl;                 if (!savefileforlater(lastpathsent.tostdstring().c_str())) {                     qdebug() << "error saving file, check if folder exists , permissions." << endl;                 }                  // generate default 1 prevent timeouts.                 qdebug() << "generate default file..." << endl;                 // ...             }              break;     }      // unlock     locksend = false;      rep->deletelater(); // prevent memory leak }  bool directorywatcher::savefileforlater(const char* pathtorequestfile) {      qfile file(pathtorequestfile);     if (!file.open(qiodevice::readonly | qiodevice::text)) {         qdebug() << "readonly , text" << endl;         return false;     }      qstring path(pathtorequestfile);     qfileinfo fileinfo(path);      qstring newpath = "c:\\data\\offline\\" + fileinfo.filename();      return file.copy(newpath);  } 

thanks help.

the possible reason 2 emits of directorychanged normal editor when saving changes removes , writes new version of file disk. that's why there 1 signal when file removed , 1 when it's recreated.