如何在C++的Qt中检查文件是否存在

84

我怎样在Qt中检查给定路径下是否存在文件?

我的当前代码如下:

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

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

然而当我运行这段代码时,尽管我所提供的路径下的文件不存在,但它并没有输出handleError中指定的错误信息。


2
我认为下面的@mozzbozz可能有你的答案 - 别忘了接受/给分 :) - Rachael
5个回答

111

(TL;DR在底部)

我会使用QFileInfo-class (文档) - 这正是它所用之处:

QFileInfo类提供独立于系统的文件信息。

QFileInfo提供有关文件名称和位置(路径)、访问权限以及它是否为目录或符号链接等信息。文件的大小和最后修改/读取时间也可以获得。 QFileInfo还可以用于获取有关Qt资源的信息。

这是检查文件是否存在的源代码:

#include <QFileInfo>

(不要忘记添加相应的 #include 语句)

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;
    }
}

还要考虑:您是否只想检查路径是否存在(exists()),还是您也想确保这是一个文件而不是目录(isFile())?

注意:exists() 函数的文档说:

如果文件存在,则返回true;否则返回false。

注意:如果文件是指向不存在文件的符号链接,则返回false。

这不是很精确。 应该是:

如果路径(即文件或目录)存在,则返回true;否则返回false。


简短版 TL;DR:

(使用上面较短的函数版本,减少几行代码)

#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();
}

针对Qt >=5.2的TL;DR

(使用Qt 5.2引入的exists作为static方法;文档中说明静态函数更快,尽管我不确定在同时使用isFile()方法时是否仍然如此;至少这是一个单行代码)

#include <QFileInfo>

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

4
只是一个建议,函数 bool fileExists(const QString &path) 中的代码可以进一步简化为:return checkFile.exists() && checkFile.isFile(); @mozzbozz - Dreamer
@Dreamer 感谢您的评论。当然,您是正确的,尽管这也是一种品味问题。我也添加了您的版本(我会将较长的版本保留在这里,因为对于初学者来说可能更容易理解)。 - mozzbozz
1
@kayleeFrye_onDeck 小心,你的编辑并不完全正确。文档确实说静态函数更快。然而,文档对函数的实际作用描述不够精确。exists函数(无论是静态还是非静态)只检查路径是否存在,而不是文件是否存在。因此,如果有一个给定路径的目录,那么你的建议也会返回true!(我在我的Qt 5.10系统上刚刚测试过)。 - mozzbozz
1
@kayleeFrye_onDeck 确定(在Windows下使用Qt 5.6测试过):https://gist.github.com/mozzbozz/2e83d7e3452a07fa817980403c42eade --> 是的,我认为这是一个误解。我的意思是exists函数(无论是否为static)如果给定路径是目录,则返回true。然而问题是“如何检查文件是否存在”(而不是目录)。请看链接的代码片段,希望能解释清楚我的意思。 - mozzbozz
1
但是等等,事情还会变得更糟糕,哈哈:https://i.imgur.com/5Hds4kA.png “文件” 叹气。 - kayleeFrye_onDeck
显示剩余3条评论

15
您可以使用 QFileInfo::exists() 静态方法:
#include <QFileInfo>
if(QFileInfo::exists("C:\\exampleFile.txt")){
    //The file exists
}
else{
    //The file doesn't exist
}

如果您希望只有在文件存在时返回true,路径存在但是是文件夹则返回false,您可以将其与QDir::exists()结合使用:

#include <QFileInfo>
#include <QDir>
QString path = "C:\\exampleFile.txt";
if(QFileInfo::exists(path) && !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
}

请注意:如果您提供一个目录路径,您的源代码也会返回“true”,即使它只是一个文件。OP要求检查文件,而不是路径。 - mozzbozz
1
如果您希望在路径存在但是是文件夹的情况下返回false,您可以使用QFileInfo(path).exists() && !QDir(path).exists()。我已经编辑了我的答案以添加这一点。 - Donald Duck

8

您发布的代码是正确的。很有可能是其他地方出了问题。

尝试添加这段代码:

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

在handleError函数内部。如果上面的消息打印出来了,那么你知道有其他问题。


3

这是我检查数据库是否存在的方法:

#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 !";
}

使用 SQLite 时,要检查数据库是否存在比较困难,因为如果不存在它会自动创建一个新的数据库。


3
这与问题有何关联? - HiFile.app - best file manager
哎呀?这完全不相关。 - Imeguras
使用QFileInfo检查文件的方法已经在其他答案中涵盖。 - General Grievance

1

我会完全跳过使用Qt的任何东西,而只使用旧的标准access

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

@Styne666:我所知道的Windows上的每个编译器都支持access,当然包括MS和gcc端口。Intel使用MS库,该库支持它,而Comeau使用后端编译器的库。 - Jerry Coffin
感谢让我进行研究。我认为这种方法可能看起来可行,但考虑到此答案的评论,如果您有Qt项目,坚持使用Qt的选项仍然是更好的解决方案。 - Samuel Harmer
2
@Styne666:我不确定Qt是否提供任何解决setuid/setgid程序问题的东西,这似乎是唯一重要的问题。他们争论“跨平台”的含义以及应该关注哪些标准,但如果我们只关心Qt支持的平台,那么这些问题大多都是无关紧要的。 - Jerry Coffin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接