Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Issues with qtDir::exist



  • Hello Everyone, I am having an issue with qtDir::exist on Centos 7 Machine. Essentially the problem boils down the the a piece of code that look like below:

    void exists(const QString& temp){
    	QDir d(temp);
    	qDebug() << "d: play create? " << d.exists();
    }
    
    int main(int argc, char *argv[]){
    	QCoreApplication a(argc, argv);
    	QString str = "play";
    	QString path = QString("temp/%1").arg(str);
    	QDir dir(path);
    	if(!dir.exists()){
    	    if(dir.mkpath(".")) qDebug() << "play created";
    	}
    	exists(path);
    	return a.exec();
    }
    

    What is happening is that, inside the exist function the output is "d: play create? false". This should only happen if the directory does not exists or if we have a file with the same name as "play" instead according to this. I tried to cd to the working directory and saw that actually the play directory did actually exists and is indeed a directory and not a file.

    I am using Qt5.12.10.

    Can anyone help with what the issue maybe?



  • @Mellar said in Issues with qtDir::exist:

    qDebug() << "play created";

    Does it print "play created" at first place ?
    Does build directory where application is running has "temp/play" directory?

    Code snippet is working fine windows.



  • @Mellar
    Use an absolute path rather than a relative path, at least while you diagnose what the issue is.

    What is the point of ever going dir.mkpath(".")?? And your code will always print play created, since it will always return true.



  • @nagesh I can confirm that this also worked on a Mac. I extracted the problematic code from production code.

    Unfortunately on that production the the first "play created" qDebug statement is not available I only added this myself.
    The directory does exists yes.



  • @JonB Thanks for the comment and advice going forward. Initially the directory does not exist. it should only exist after dir.mkPath. The directory is indeed created however dir::exists does not seem to recognise that.



  • @Mellar said in Issues with qtDir::exist:

    It should only exist after dir.mkPath

    I don't know what you mean. I quoted your code:

    if(dir.mkpath("."))
    

    You are (trying to create) .. Which by definition will always exist.....

    [EDIT Hang on, I see what you mean, let me think again...]

    I get it now, I did not appreciate that dir.mkpath(".") treats . as relative to whatever is in dir.

    Although you say it is not your case, I think your code would behave as you say if temp/play exists as a file and not a directory. You might try d.mkdir() instead of d.mkpath().

    I don't know any more, and I see others are saying it works OK for them.... If it were me I'd try making the path you are playing with absolute instead of relative, so that I was sure what it was addressing, and see if that makes any difference?



  • @Mellar ,
    as @JonB already have written, I also suppose it is an issue with relative/absolute path.

    I am using this kind of test to create path if not exists with Windows/Android/Linux, so I know it works!
    I would suggest you to do following changes, only for test purpose:

    void exists(const QString& temp){
    	QDir d(temp);
    	qDebug() << "d: " << temp << " create? " << d.exists();
    }
    
    int main(int argc, char *argv[]){
    	QCoreApplication a(argc, argv);
    	QString str = "play";
    	QString path = QString("temp/%1").arg(str);
    	QDir dir(path);
    	if(!dir.exists()){
    	    if(dir.mkpath(".")) qDebug() << "play created";
    	}
    
            if(dir.exists()) qDebug() << "play found";
    	exists(path);
    	exists(dir.absolutePath());
    	return a.exec();
    }
    


  • @Mellar said in Issues with qtDir::exist:

    . I tried to cd to the working directory and saw that actually the play directory did actually exists and is indeed a directory and not a file

    Since you are referring to relative path temp/play, if shadow build is enabled then
    (eg: "build-ProjectName-Kit-Debug") this is the directory where application is generated .
    dir.exists checks for temp/play directory relative to "build-ProjectName-Kit-Debug"
    not wrt working directory.



  • Hey, thanks for all the replies. I just wanted to update that running yum update seems to have fixed the issue.
    There are some things that I came to figure out later:

    • The actual production code was running in a docker container
    • The docker container was running ubuntu 20
    • The docker host was on centOs7

    I am not sure why running yum update will have solved the issue but at least that was averted.

    Thank you once again for being so helpful.



  • @nagesh said in Issues with qtDir::exist:

    dir.exists checks for temp/play directory relative to "build-ProjectName-Kit-Debug"
    not wrt working directory.

    Hi @nagesh. I just noticed this. I also see @Christian-Ehrlicher has upvoted it, so that usually means it must be right!

    But I admit I am quite confused. How can QDir::exists() on a relative path be anything other than relative to the process's current working directory?? Where does the idea that it has anything to do with where the executable happens to be located come from?


  • Moderators

    @JonB said in Issues with qtDir::exist:

    How can QDir::exists() on a relative path be anything other than relative to the process's current working directory??

    A QDir object contains a path value (returned by QDir::path()) which is set via the constructor, or via QDir::setPath(), etc.

    QDir::exists() and other non-static methods operate on the path value stored inside the QDir object, not on the process' current working directory.

    The current working directory is retrieved via QDir::currentPath() which is a static function, independent of any value in a QDir object.



  • @JKSH
    I know this, you misunderstand my question!

    In this case, you can see from the code we have:

    QDir dir("temp/play");
    qDebug() << dir.exists();
    

    As you can see, the path is relative. I say that means it will look relative to whatever the current working directory is. However @nagesh has written (and @Christian-Ehrlicher has upvoted!):

    dir.exists checks for temp/play directory relative to "build-ProjectName-Kit-Debug"
    not wrt working directory.

    I want evidence that it will seek the file relative to the build output directory and "not wrt working directory"?


  • Lifetime Qt Champion

    @JonB said in Issues with qtDir::exist:

    I want evidence that it will seek the file relative to the build output directory and "not wrt working directory"?

    This thread is old and you're correct. I was wrong.

    build-ProjectName-Kit-Debug and working directory is only the same when started from Qt-Creator and the default values for the debugging are not modified and when the cwd is not modified within the application (e.g. due to chdir() or QFileDialog::getOpen/SaveFileName())



  • @Christian-Ehrlicher
    Ah ha, thank you for clarifying!

    Now, you say:

    build-ProjectName-Kit-Debug and working directory is only the same when started from Qt-Creator

    I was about to add a "P.S." saying this would only be the case if Creator changed the working directory to the build output directory when launching the executable from within it. You are saying that is indeed the case. If so that is something of which I was not aware! Is there a doc reference stating this is the case from Creator, perhaps if you have this "shadow build" switched on?? I (think I) assumed the current directory from a Creator-launched executable was always the directory containing the .pro file??


  • Lifetime Qt Champion

    @JonB The default working dir can be set in the project config of QtCreator and is by default set to the build dir.



  • @Christian-Ehrlicher said in Issues with qtDir::exist:

    is by default set to the build dir

    Ohhhh! I had not noticed that! Partly because when I started out on Qt I was using Python/PyQt5/PyCharm, which obviously does not have a "build directory" nor a .pro file. When I changed over to C++ + Creator I just never looked for this.....


Log in to reply