Qt 之遍历文件夹(经典详解)

    科技2025-04-26  9

    文章目录

    前言一、Qt 遍历文件夹下一层的文件:1、方式 1:2、方式2: 二、级联遍历文件夹及其子孙文件夹中的文件1.方式1:2.方式2:3.关于 QFileInfo 获取文件信息的方法可以查看 API


    前言

    关于 Qt 操作文件夹、文件的知识用途较多,比如遍历下一层乃至所有子孙文件、文件夹,获取它们的一些信息(大小、类型、最后更改时间等)。当然,也可以进行级联删除。 首先看简单的:

    一、Qt 遍历文件夹下一层的文件:

    1、方式 1:

    void ImageTree::addFolderImages(QString path) { // 判断路径是否存在 QDir dir(path); if(!dir.exists()) { return; } dir.setFilter(QDir::Files | QDir::NoSymLinks); QFileInfoList list = dir.entryInfoList(); int file_count = list.count(); if(file_count <= 0) { return; } QStringList string_list; for(int i=0; i<file_count; i++) { QFileInfo file_info = list.at(i); QString suffix = file_info.suffix(); if(QString::compare(suffix, QString("png"), Qt::CaseInsensitive) == 0) { QString absolute_file_path = file_info.absoluteFilePath(); string_list.append(absolute_file_path); } } }

    分析:遍历文件的下一层,对于系统而言包括:文件夹、文件、快捷方式,使用 setFilter 即可过滤。通过 entryInfoList 则可以获取过滤后所得到的文件夹下的文件信息列表,遍历文件通过操作 QFileInfo 可得到所需的文件详细信息(大小、类型、后缀等)。

    2、方式2:

    void ImageTree::addFolderImages(QString path) { // 判断路径是否存在 QDir dir(path); if(!dir.exists()) { return; } QStringList filters; filters<<QString("*.jpeg")<<QString("*.jpg")<<QString("*.png")<<QString("*.tiff")<<QString("*.gif")<<QString("*.bmp"); dir.setFilter (QDir::Files | QDir::NoSymLinks); // 设置类型过滤器,只为文件格式 dir.setNameFilters (filters); // 设置文件名称过滤器,只为 filters 格式(后缀为.jpeg 等图片格式) int dir_count = dir.count(); if(dir_count <= 0) { return; } QStringList string_list; // 获取分隔符 //QChar separator = QDir::separator(); QChar separator = QChar('/'); if(!path.contains(separator)) { separator = QChar('\\'); } QChar last_char = path.at(path.length()-1); if(last_char == separator) { separator = QChar(); } for(uint i=0; i<dir_count; i++) { QString file_name = dir [i]; // 文件名称 QString file_path = path + separator + file_name; // 文件全路径 string_list.append(file_path); } //string_list 添加完成之后,就可以查看 list 中的文件路径了 }

    分析:setNameFilters 顾名思义,就是过滤文件名称的。如果只需要获取指定路径下的文件名,则可去掉 “获取分隔符” 部分代码(因为我是为了获取文件的全路径)。

    思考:QDir::separator () 这是用于获取分隔符的,调试过程中发现 path 的分隔符为 ‘/’,奇怪的是获取到的为 ‘\’,刚好相反,所以我通过 contains 的方式获取分隔符的(无非 ‘/’ 与 ‘\’)。

    讨论:如果设定 filters 后,那么存在一定的问题。熟用 Windows 的应该都知道,文件名是忽略大小写的(包括扩展名),那么若 filters 设定了 “.jpg” 之后,则就不可添加扩展名为 “.JPG”、“.Jpg” 等大小写兼有的文件了。 既然有问题,就有解决问题的方式。 1、问题来源是由扩展名引起,那么去掉 setNameFilters (filters); 2、上述已经获取文件全路径,那么 QFileInfo file_info(file_path)获取文件信息的对象 3、通过 file_info.suffix () 或者 completeSuffix () 来判定文件的后缀、扩展名 4、获取之后比较时忽略大小写即可。如:QString::compare (suffix, QString (".jpeg"), Qt::CaseInsensitive) == 0

    总结:通过以上两种方式比较,关于遍历下一层的方式,采用 “方式 1” 较好。

    二、级联遍历文件夹及其子孙文件夹中的文件

    1.方式1:

    void ImageTree::addSubFolderImages(QString path) { // 判断路径是否存在 QDir dir(path); if(!dir.exists()) { return; } // 获取所选文件类型过滤器 QStringList filters; filters<<QString("*.jpeg")<<QString("*.jpg")<<QString("*.png")<<QString("*.tiff")<<QString("*.gif")<<QString("*.bmp"); // 定义迭代器并设置过滤器 QDirIterator dir_iterator(path, filters, QDir::Files | QDir::NoSymLinks, QDirIterator::Subdirectories); QStringList string_list; while(dir_iterator.hasNext()) { dir_iterator.next(); QFileInfo file_info = dir_iterator.fileInfo(); QString absolute_file_path = file_info.absoluteFilePath(); string_list.append(file_path); } }

    分析:QDirIterator 定义过程中可设置过滤器,包括:文件名称、文件类型等。dir_iterator.next () 这句话很重要,如果缺少将会进入死循环!

    2.方式2:

    QStringList string_list; void ImageTree::addSubFolderImages(QString path) { QDir dir(path); if(!dir.exists()) { return; } dir.setFilter(QDir::Dirs | QDir::Files | QDir::NoSymLinks); dir.setSorting(QDir::DirsFirst); QFileInfoList list = dir.entryInfoList(); int i = 0; bool is_dir; do { QFileInfo file_info = list.at(i); if(file_info.fileName() == "." | file_info.fileName() == "..") { i++; continue; } is_dir = file_info.isDir(); if(is_dir) { // 进行递归 addSubFolderImages(file_info.filePath()); } else { // 获取文件后缀并获取所选包含类型,若存在包含类型且后缀相同,则添加 QString suffix = file_info.suffix(); if(QString::compare(suffix, QString("png"), Qt::CaseInsensitive) == 0) { QString absolute_file_path = file_info.absoluteFilePath(); string_list.append(absolute_file_path); } } i++; } while(i<list.size()); }

    分析:此方式采用递归的思路解决,也是网上大多数人用的办法,个人建议摒弃!递归的效率真心不敢接受,而且代码看起来也费劲。

    总结:通过以上两种方式比较,关于遍历子孙文件夹的方式,采用 “方式 1” 较好。

    3.关于 QFileInfo 获取文件信息的方法可以查看 API

    void setFile(const QString &file); void setFile(const QFile &file); void setFile(const QDir &dir, const QString &file); bool exists() const; void refresh(); QString filePath() const; QString absoluteFilePath() const; QString canonicalFilePath() const; QString fileName() const; QString baseName() const; QString completeBaseName() const; QString suffix() const; QString bundleName() const; QString completeSuffix() const; QString path() const; QString absolutePath() const; QString canonicalPath() const; QDir dir() const; QDir absoluteDir() const; bool isReadable() const; bool isWritable() const; bool isExecutable() const; bool isHidden() const; bool isNativePath() const; bool isRelative() const; inline bool isAbsolute() const { return !isRelative(); } bool makeAbsolute(); bool isFile() const; bool isDir() const; bool isSymLink() const; bool isRoot() const; bool isBundle() const; QString readLink() const; inline QString symLinkTarget() const { return readLink(); } QString owner() const; uint ownerId() const; QString group() const; uint groupId() const; bool permission(QFile::Permissions permissions) const; QFile::Permissions permissions() const; qint64 size() const; QDateTime created() const; QDateTime lastModified() const; QDateTime lastRead() const; bool caching() const; void setCaching(bool on);
    Processed: 0.008, SQL: 8