ChatGPT解决这个技术问题 Extra ChatGPT

How to check whether file exists in Qt in c++

How do I check whether a file exists in a given path or not in Qt?

My current code is below:

QFile Fout("/Users/Hans/Desktop/result.txt");

if(!Fout.exists()) 
{       
  eh.handleError(8);
}  
else
{
  // ......
}

But when I run the code it is not giving the error message specified in handleError even though the file I mentioned in the path does not exist.

I think @mozzbozz below may have your answer--don't forget to accept/give points :)

m
mozzbozz

(TL;DR at the bottom)

I would use the QFileInfo-class (docs) - this is exactly what it is made for:

The QFileInfo class provides system-independent file information. QFileInfo provides information about a file's name and position (path) in the file system, its access rights and whether it is a directory or symbolic link, etc. The file's size and last modified/read times are also available. QFileInfo can also be used to obtain information about a Qt resource.

This is the source code to check whether a file exists:

#include <QFileInfo>

(don't forget to add the corresponding #include-statement)

bool fileExists(QString path) {
    QFileInfo check_file(path);
    // check if file exists and if yes: Is it really a file and no directory?
    if (check_file.exists() && check_file.isFile()) {
        return true;
    } else {
        return false;
    }
}

Also consider: Do you only want to check if the path exists (exists()) or do you want to also make sure that this is a file and not a directory (isFile())?

Be careful: The documentation of the exists()-function says:

Returns true if the file exists; otherwise returns false. Note: If file is a symlink that points to a non-existing file, false is returned.

This is not precise. It should be:

Returns true if the path (i.e. file or directory) exists; otherwise returns false.

TL;DR

(with shorter version of the function above, saving a few lines of code)

#include <QFileInfo>

bool fileExists(QString path) {
    QFileInfo check_file(path);
    // check if path exists and if yes: Is it really a file and no directory?
    return check_file.exists() && check_file.isFile();
}

TL;DR for Qt >=5.2

(using exists as a static which was introduce in Qt 5.2; the docs say the static function is faster, though I'm not sure this is still the case when also using the isFile() method; at least this is a one-liner then)

#include <QFileInfo>

// check if path exists and if yes: Is it a file and no directory?
bool fileExists = QFileInfo::exists(path) && QFileInfo(path).isFile();

Just a suggestion, the code in function bool fileExists(const QString &path) could be further simplified to: return checkFile.exists() && checkFile.isFile(); @mozzbozz
@Dreamer Thanks for your comment. Of course you are right, although it is also a matter of taste. I've added your version, too (I will leave the longer version here as it might be easier to follow for beginners).
@kayleeFrye_onDeck Be careful, your edit is not really correct. It is right that the docs say that the static function is faster. However, the docs are quite unprecise about what the function really does. The exists function (static or not) only checks if the path exists, not if there is a file. So, if there is a directory with the given path, then your suggestion will also return true! (just tested it on my system with Qt 5.10)
@kayleeFrye_onDeck Sure (tested with Qt 5.6 under Windows): gist.github.com/mozzbozz/2e83d7e3452a07fa817980403c42eade --> Yes, I think this is a misunderstanding. I meant the exists function (static or not) returns true if the given path is a directory. However the question was "How do I check whether a file exists" (and not directory). Take a look at the linked code snippet, I hope that explains what I mean.
But wait, it gets worse haha: i.imgur.com/5Hds4kA.png "file" sigh
D
Donald Duck

You can use the QFileInfo::exists() method:

#include <QFileInfo>
if(QFileInfo("C:\\exampleFile.txt").exists()){
    //The file exists
}
else{
    //The file doesn't exist
}

If you want it to return true only if the file exists and false if the path exists but is a folder, you can combine it with QDir::exists():

#include <QFileInfo>
#include <QDir>
QString path = "C:\\exampleFile.txt";
if(QFileInfo(path).exists() && !QDir(path).exists()){
    //The file exists and is not a folder
}
else{
    //The file doesn't exist, either the path doesn't exist or is the path of a folder
}

Be careful: If you give a path to a directory, your source code will also return true, even though it is "only" a file. The OP asked to check for a file, not a path.
@mozzbozz If you want it to return false if the path exists but is a folder, you can do QFileInfo(path).exists() && !QDir(path).exists(). I've edited my answer to add that.
A
Anthony

The code you've posted is correct. Chances are that something else is wrong.

Try putting this:

qDebug() << "Function is being called.";

inside of your handleError function. If the above message prints, you know something else is the problem.


f
fredmaggiowski

That's how I check if the database exists:

#include <QtSql>
#include <QDebug>
#include <QSqlDatabase>
#include <QSqlError>
#include <QFileInfo>

QString db_path = "/home/serge/Projects/sqlite/users_admin.db";

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(db_path);

if (QFileInfo::exists(db_path))
{
    bool ok = db.open();
    if(ok)
    {
        qDebug() << "Connected to the Database !";
        db.close();
    }
}
else
{
    qDebug() << "Database doesn't exists !";
}

With SQLite it's difficult to check if the database exists, because it automatically creates a new database if it doesn't exist.


how does this relate to the question?
J
Jerry Coffin

I would skip using anything from Qt at all, and just use the old standard access:

if (0==access("/Users/Hans/Desktop/result.txt", 0))
    // it exists
else
    // it doesn't exist

@Styne666: Every compiler of which I'm aware on Windows supports access -- certainly MS, and the gcc ports. Intel uses the MS library, which supports it, and Comeau uses the library of the back-end compiler.
Thank you for making me do my research. I accept this may appear to work, but taking into account the comments on this answer I still think sticking with Qt's options (if you have a Qt project) is a better solution.
@Styne666: I'm not at all sure Qt provides anything to fix the problem for setuid/setgid programs, which seems to be about the only one that matters. They argued about the meaning of "cross platform" and which standards to care about, but if we only care about the platforms supported by Qt, those are mostly moot points.