9.3 目录操作和文件系统

9.3 目录操作和文件系统

  在Qt中,我们常常会使用QFile来完成对文件的一些常用的操作,比如读写文件又或者是将文件对象作为参数放到文本流QTextStream或者是QDataStream中进行更为细化的处理。那么除了文件之外,还有目录,那么同样的,Qt中也提供了用于处理目录的类——QDir。通过这个类,可以非常方便的完成对目录的相关操作,例如存取目录或获取目录中的文件信息,操作底层的文件系统并且还可以用来间接操作Qt的资源文件等。

  Qt使用'/'来作为通用的目录分隔符,实际上在实际的应用中也建议使用'/'作为路径的分隔符,因为Windows下习惯使用'\'来作为分隔符,但是我们知道'\'的转义字符是'\\',并且在Linux下是不认识Windows这种所谓的反斜杠的分隔符的,但是Windows却兼容使用'/'作为目录分隔符,如此一来,为了兼容性,建议以后的路径分隔符都统一采用'/'而不是'\'。

  QDir类中可以使用相对路径或绝对路径指向某个文件,比如其成员方法isRelative()和isAbsolute()就可以判断QDir对象使用的是相对路径还是绝对路径。如果需要将一个相对路径转换为绝对路径,可以使用其成员方法makeAbsolute()函数。

  目录的路径可以使用QDir::path()方法返回,如果要设置新的路径,那么可以使用setPath()函数来设置新的路径。绝对路径可以使用absolutePath()返回,要获取目录名,则可以使用dirName(),它通常会返回绝对路径中的最后一级目录的名称。另外,我们在Linux里面用'.'和'..'来表示当前目录或上级目录。我们同样可以使用QDir的cd()和cdUp()来返回当前目录或返回上级目录。对应目录的一些修改,我们可以使用mkdir()来创建目录以及可以使用rename()来改变目录的名称。

  目录若要判断是否存在,则可以使用exists(),目录的属性可以使用isReadable()函数,isAbsolute()函数、isRelative()和isRoot()来获取。另外目录下可能会有很多的条目,比如文件,目录或软链接,这些条目的总数可以使用count()方法来进行统计。entryList()则可以返回目录下所有条目组成的字符串的链表。我们还可以使用remove()方法来删除文件,使用rmdir()来删除目录。

  9.3.1 文件大小及路径获取实例

  下面通过一个实例来介绍一下如何得到一个文件的大小以及所在的目录的路径,同样的这还是一个控制台应用。如何建立控制台应用在前面已经讲过,这里不在赘述。在main.cpp中写以下内容:

#include <QCoreApplication>
#include <QStringList>
#include <QDir>
#include <QDebug>
qint64 du(const QString&path)
{
    QDir dir(path);
    qint64 size(0);
    foreach(const QFileInfo&fileInfo,dir.entryInfoList(QDir::Files))//该步骤是用于遍历目录中的文件,并获取每一个文件的大小,然后将文件的大小进行累加
    {
        size += fileInfo.size();
    }
    foreach(const QString&subDir,dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot))//该步骤用于递归获取目录中的其他目录
    {
        size += du(path+QDir::separator()+subDir);//假如目录中还有一些内容需要遍历,这里就需要做递归处理
        //separator()返回的是文件系统的分隔符
    }
    char unint = 'B';
    qint64 curSize = size;
    if(curSize>1024)
    {
        curSize /= 1024;
        unint = 'K';
        if(curSize > 1024)
        {
            curSize /= 1024;
            unint = 'M';
            if(curSize > 1024)
            {
                curSize /= 1024;
                unint = 'G';
            }
        }
    }
    qDebug() << curSize << unint << "\t" << qPrintable(path);
    return size;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QString path;
    QStringList args = a.arguments();
    if(args.count() > 1)
    {
        path = args[1];
    }
    else
    {
        path = QDir::currentPath();
    }
    qDebug() << path << endl;
    du(path);
    return a.exec();
}

  运行如图所示

  9.3.2 文件系统浏览器实例

  文件系统浏览是目录操作中的一种常用的功能,这里通过实现一个能够显示所有文件的文件系统浏览器的浏览功能,介绍如何使用QDir显示文件系统及使用过滤显示文件的方法。完成该功能,需要建立Qt的GUI项目。因此,我们需要建立一个新的Qt GUI的项目。

   (1)建立Qt的GUI程序,并将项目名称命名为FileView,基类选择继承自QDialog。不需要创建UI界面。

  (2)在fileview.h中添加如下成员

#ifndef FILEVIEW_H
#define FILEVIEW_H

#include <QDialog>
#include <QFileInfoList>
#include <QLineEdit>
#include <QFileInfo>
#include <QDir>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QListWidgetItem>
class FileView : public QDialog
{
    Q_OBJECT
public:
    FileView(QWidget *parent = nullptr);
    ~FileView();
public:
    void showFileInfoList(QFileInfoList list);//用于在初始状态下,列出根目录的内容
public slots:
    void slotShow(QDir dir);//显示进入到目录中的内容
    void slotDirShow(QListWidgetItem*item);//双击目录后,进入到目录中
private:
    QLineEdit*m_fileLineEdit;
    QListWidget*m_fileListWidget;
    QVBoxLayout*m_mainLayout;
};
#endif // FILEVIEW_H

  (3)在fileview.cpp中进行实现

#include "fileview.h"

FileView::FileView(QWidget *parent):QDialog(parent)
{
    m_mainLayout = new QVBoxLayout(this);
    m_fileLineEdit = new QLineEdit("/");
    m_fileListWidget = new QListWidget;
    m_mainLayout->addWidget(m_fileLineEdit);
    m_mainLayout->addWidget(m_fileListWidget);

    connect(this->m_fileLineEdit,SIGNAL(returnPressed()),this,SLOT(slotShow(QDir)));
    connect(this->m_fileListWidget,&QListWidget::itemDoubleClicked,this,&FileView::slotDirShow);

    QString root = "/";//默认情况下,显示磁盘根目录的内容
    QDir rootDir(root);
    QStringList string;
    string << "*";//这个是过滤器,这个会过滤出符合这里面名称要求的文件名或目录名,如果是*则表示一切都可以
    QFileInfoList list = rootDir.entryInfoList(string,QDir::AllEntries,QDir::DirsFirst|QDir::Size);//获取根目录中的内容
    /*
     *在进行entryInfoList时,这里面会有一些排序的和筛选的规则
     *
     * //过滤器的规则
        QDir::Dirs 按照过滤方式列出所有目录
        QDir::AllDirs 列出所有目录,但不考虑过滤方式
        QDir::Files 只列出文件
        QDir::Drives 列出磁盘驱动器(对于Unix系统无效)
        QDir::NoSymLinks 不列出符号链接(软链接)(对于不支持符号链接的操作系统无效)
        QDir::NoDotAndDotDot = NoDot|NoDotDot 不列出.和..这两个特殊目录
        QDir::NoDot 不列出.目录
        QDir::NoDotDot 不列出..目录
        QDir::AllEntries = Dirs|Files|Drives 列出目录,文件和磁盘驱动器
        QDir::Readable 列出所有具有读属性的文件和目录
        QDir::Writable 列出所有具有写属性的文件和目录
        QDir::Executable 列出所有具有可执行属性的文件和目录
        QDir::Modified 列出所有被修改过的文件(对于Unix系统无效)
        QDir::Hidden 列出隐藏文件
        QDir::System 列出系统文件(在Unix下指FIFO和套接字和所谓的设备文件)
        QDir::CaseSensitive 文件系统若区分文件名大小写(比如Linux和Unix系统),则按照大小写方式进行过滤
      * //排序器的规则
        QDir::Name 按照名称排序
        QDir::Time 按照时间排序
        QDir::Size 按照文件大小排序
        QDir::Type 按照文件类型排序
        QDir::Unsorted 不排序
        QDir::NoSort 没有排序规则(默认)
        QDir::DirsFirst 目录优先
        QDir::DirsLast 目录最后
        QDir::Reversed 反序
        QDir::IgnoreCase 忽略大小写
        QDir::LocaleAware 使用本地的排序方式进行排序
    */
    showFileInfoList(list);//显示根目录中的内容
}

FileView::~FileView()
{
}
//当用户双击浏览器中的目录时,会进入下一级目录中,或单击..以返回上一级目录
void FileView::showFileInfoList(QFileInfoList list)
{
    foreach (const QFileInfo&fileInfo,list)
    {
        if(fileInfo.isDir())
        {
            QIcon dirIcon(":/icon/dir.png");
            m_fileListWidget->addItem(new QListWidgetItem(dirIcon,fileInfo.fileName()));
        }
        else if(fileInfo.isFile())
        {
            QIcon fileIcon(":/icon/file.png");
            m_fileListWidget->addItem(new QListWidgetItem(fileIcon,fileInfo.fileName()));
        }
    }
}
//该函数会用于显示出目录中所有内容
void FileView::slotShow(QDir dir)
{
    m_fileListWidget->clear();
    foreach(const QFileInfo&fileInfo,dir.entryInfoList(QDir::AllEntries,QDir::DirsFirst|QDir::Size))
    {
        if(fileInfo.isDir())
        {
            QIcon dirIcon(":/icon/dir.png");
            m_fileListWidget->addItem(new QListWidgetItem(dirIcon,fileInfo.fileName()));
        }
        else if(fileInfo.isFile())
        {
            QIcon fileIcon(":/icon/file.png");
            m_fileListWidget->addItem(new QListWidgetItem(fileIcon,fileInfo.fileName()));
        }
    }
}
//该函数会通过LineEdit传入的目录来获取从哪个目录开始浏览数据
void FileView::slotDirShow(QListWidgetItem *item)
{
    QString str = item->text();//先获取到item上的字符串
    QDir dir;
    dir.setPath(m_fileLineEdit->text());//设置路径为LineEdit中的路径
    dir.cd(str);//进入到用户选择的Dir里面
    m_fileLineEdit->setText(dir.absolutePath());//然后将LineEdit中的路径刷新一下
    slotShow(dir);//显示内容
}

  (4)运行程序

  本节代码:https://files.cnblogs.com/files/blogs/792763/DirTest.zip?t=1720179963&download=true

 

posted @ 2024-07-05 19:46  蜡笔小新Pointer  阅读(36)  评论(0)    收藏  举报