Qt之遍歷文件夾

轉載:http://blog.sina.com.cn/s/blog_a6fb6cc90101f1ur.html
關於Qt操作文件夾、文件的知識用途較多,比如遍歷下一層乃至所有子孫文件、文件夾,獲取它們的一些信息(大小、類型、最後更改時間等)。當然,也可以進行級聯刪除
    首先看簡單的:

一、Qt遍歷文件夾下一層的文件:
方式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
    {
        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:
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
    {
        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:
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:
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
}
    分析:此方式採用遞歸的思路解決,也是網上大多數人用的辦法,個人建議摒棄!遞歸的效率真心不敢接受,而且代碼看起來也費勁。

    總結:通過以上兩種方式比較,關於遍歷子孫文件夾的方式,採用“方式1”較好。

關於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);

更多關於獲取文件圖標、類型的詳細信息請查看:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章