文件目录操作相关类

Qt 为文件和目录操作提供了一些类,利用这些类可以方便地实现一些操作。Qt 提供的与文件和目录操作相关的类包括以下几个:

  • QCoreApplication:用于提取应用程序路径,程序名等文件信息;
  • QFile:除了打开文件操作外,QFile 还有复制文件、删除文件等功能;
  • QFileInfo:用于提取文件信息,包括路径、文件名、后缀等;
  • QTemporaryDir 和 QTemporaryFile:用于创建临时目录和临时文件;
  • QFileSystemWatcher:文件和目录监听类,监听目录下文件的添加、删除等变化,监听文件修改变化。

这些类基本涵盖了文件操作需要的主要功能,有些功能还在某些类中重复出现,例如 QFile 和 QDIr 都具有删除文件、判断文件是否存在的功能。

实例概述

QCoreApplication 类

QCoreApplication 是为无 GUI 应用程序提供事件循环的类,是所有应用程序类的基类,其子类 QGuiApplication 为有 GUI 界面的应用程序提供流控制和主要设定,QGuiApplication 的子类 QApplication 为基于 QWidget 的应用程序提供支持,包括界面的初始化等。

QCoreApplication 提供了一些有用的静态函数,可以获取应用程序名称、启动路径等信息,几个函数的名称和功能如下:

| 函数原型 | 功能 |
| — | — |
| QString applicationDirPath() | 返回应用程序的启动路径 |
| QString applicationFilePath() | 返回应用程序的带有目录的完整文件名 |
| QString applicationName() | 返回应用程序名称,无路劲无后缀 |
| QStringList libraryPaths() | 返回动态加载库文件时应用程序搜索的目录列表 |
| void setOrganizationName(QString& orgName) | 为应用程序设置一个机构名 |
| QString organizationName() | 返回应用程序的机构名 |
| void exit() | 退出应用程序 |

QFile 类

前面两篇文章使用 QFile 类进行文件操作,使用了 QFile::open()函数。除了打开文件提供读写操作外,QFile 还有一些静态函数和成员函数用于文件操作。

| 函数原型 | 功能 |
| — | — |
| bool copy(QString& fileName, QSTring& newName) | 复制文件 |
| bool rename(QString& oldName, QString& newName) | 重命名文件 |
| bool remove() | 删除一个文件 |
| bool exists() | 判断文件是否存在 |
| bool setPermissions(Permissions permissions) | 设置文件的权限,权限类型是枚举类型。 |
| Permissions permissions() | 返回文件的权限 |

静态函数时无需创建 QFile 类对象实例就可以调用的函数,例如使用静态函数 exists()判断一个文件是否存在的代码如下:

void Dialog::on_pushButton_51_clicked()
{
    showBtnInfo(sender());
    QString sous=ui->editFile->text(); //源文件
    bool the=QFile::exists(sous);
    if(the)
        ui->plainTextEdit->appendPlainText(+"true \n");
    else
        ui->plainTextEdit->appendPlainText(+"false \n");
}

QFile 还提供了对应的函数成员如下(省略函数参数中的 const 关键字):

| 函数原型 | 功能 |
| — | — |
| void setFileName(QString& name) | 设置文件名,文件已打开后不能调用此函数 |
| bool copy(QString& newName) | 当前文件复制为 newName 表示的文件 |
| bool rename(QString& newName) | 将当前文件重命名为 newName |
| bool remove() | 删除当前文件 |
| bool exists() | 判断当前文件是否存在 |
| bool setPermissions(Permissions permissions) | 设置文件权限 |
| Permissions permissions() | 返回文件权限 |
| qint64 size() | 返回文件的大小、字节数 |

创建 QFile 对象时可以在构造函数里指定文件名,也可以用 setFileName()指定文件,但是文件打开后不能再调用 setFileName()函数。指定的文件作为 QFile 对象的当前文件,然后成员函数 copy()rename()等都是基于当前文件的操作。

QFileInfo 类

QFileInfo 类的接口函数提供文件的各种信息。QFileInfo 对象创建时可以指定一个文件名作为当前文件,也可以用 setFile() 函数指定一个文件作为当前文件。

QFileInfo 常见接口函数如下所示。除了一个静态函数 exists()之外,其他都是公共接口函数,接口函数的操作都是针对当前文件:

| 函数原型 | 功能 |
| — | — |
| void setFile(QString& file) | 设置一个文件名,作为 QFileInfo 操作的文档 |
| QString absoluteFilePath() | 返回带有文件名的绝对路径 |
| QString absolutePath() | 返回绝对路径,不带文件名 |
| QString fileName() | 返回去除路劲的文件名 |
| QString filePath() | 返回包含路径的文件名 |
| QString path() | 返回不含文件名的路径 |
| qint64 size() | 返回文件大小,以字节为单位 |
| QString baseName() | 返回文件基名,第一个”.“之前的文件名 |
| QString completeBaseName() | 返回文件基名,最后一个”.“之前的文件名 |
| QString suffix() | 最后一个”.“之后的后缀 |
| QString completeSuffix() | 第一个”.“之后的后缀 |
| bool isDIr() | 判断当前对象是否是一个目录或目录快捷方式 |
| bool isFile() | 判断当前对象是否是一个文件或快捷方式 |
| bool isExecutable() | 判断当前文件是否是可执行文件 |
| QDataTime created() | 返回文件创建时间 |
| QDataTime lastModified | 返回文件最后一次被修改的时间 |
| QDataTime lastRead() | 返回文件最后一次被读取的时间 |
| bool exists() | 判断文件是否存在 |
| bool exists(QString& file) | 静态函数,判断 file 表示的文件是否存在 |

QFileInfo 提供的这些函数可以提取文件信息,包括目录名、文件基名、文件后缀等,利用这些函数可以实现灵活的文件操作。例如,下面的代码是利用 QFile::rename()函数和 QFileInfo 的一些功能实现的文件重命名功能的代码,其中就用到了提取路径、提取文件基名的功能。

void Dialog::on_pushButton_50_clicked()
{//QFile::rename()
    showBtnInfo(sender());
    QString sous=ui->editFile->text(); //源文件
    QFileInfo   fileInfo(sous);//源文件信息
    QString newFile=fileInfo.path()+"/"+fileInfo.baseName()+".XYZ"; //更改文件后缀为".XYZ"
    QFile::rename(sous,newFile); //重命名文件
    ui->plainTextEdit->appendPlainText("源文件:"+sous);
    ui->plainTextEdit->appendPlainText("重命名为:"+newFile+"\n");
}

QDir 类

QDir 是进行目录操作的类,在创建 QDir 对象时传递一个目录字符串作为当前目录,然后 QDir 函数就可以针对当前目录或目录下的文件进行操作。

| 函数原型 | 功能 |
| — | — |
| QString tempPath() | 返回临时目录名称 |
| QString rootPath() | 返回根目录名称 |
| QString homePath() | 返回主目录名称 |
| QString currentPath() | 返回当前目录名称 |
| bool setCurrent(QString& paht) | 设置 path 表示的目录为当前目录 |
| QFileInfoList drives() | 返回系统的根目录列表,在 Windows 上是盘符 |

在使用 QFileDialog 选择打开一个文件或目录时需要传递一个初始目录,这个时候就可以使用 QDir::currentPath()获取应用程序当前目录作为初始目录,前面一些实例程序的代码中已经用到过这个功能。

QDir 的一些公共函数接口如下:

| 函数原型 | 功能 |
| — | — |
| QString absoluteFilePath(QString& fileName) | 返回当前目录下的一个文件的含绝对路径文件名 |
| QString absolutePath() | 返回当前目录的绝对路径 |
| QString canonicalPath() | 返回当前目录的标准路径 |
| QString filePath(QString& fileName) | 返回目录下一个文件的目录名 |
| QString dirName() | 返回最后一级目录的名称 |
| bool exists() | 判断当前目录是否存在 |
| QStringList entryList(Filters filters = NoFilter, SortFlag sort = NoSort) | 返回目录下的所有文件名,子目录名等 |
| bool mkdir(QString& dirName) | 在当前目录下建一个名称为 dirName 的目录 |
| bool rmdir(QString& dirName) | 删除指定的目录 |
| bool remove(QString& fileName) | 删除当前目录下的文件 fileName |
| bool rename(QString& oldName, QString& newName) | 将文件或目录 oldName 改为 newName |
| void setPath(QString& path) | 设置 QDir 对象的当前目录 |
| bool removeRecursively() | 删除当前目录及其下面的所有文件 |

获取目录下的目录或文件列表的函数 entryList()需要传递 QDir::Filter枚举类型的参数以获取不同的结果,QDir::Filter枚举类型的常用取值如下:

  • QDIr::AllDirs:列出所有目录名;
  • QDir::Files:列出所有文件;
  • QDir::Drives:列出所有盘符(Unix 系统下无效);
  • QDir::NoDotAndDotDot:不列出特殊符号,如“.”和“..”;
  • QDir::AllEntries:列出目录下所有项目。

列出所有子目录的程序如下:

void Dialog::on_pushButton_11_clicked()
{//列出子目录
    showBtnInfo(sender());

    QDir    dir(ui->editDir->text());
    QStringList strList=dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

    ui->plainTextEdit->appendPlainText("所选目录下的所有目录:");
    for(int i=0;i<strList.count();i++)
        ui->plainTextEdit->appendPlainText(strList.at(i));
    ui->plainTextEdit->appendPlainText("\n");

}

列出一个目录下所有文件的程序如下:

void Dialog::on_pushButton_17_clicked()
{//列出所有文件
    showBtnInfo(sender());
    QDir    dir(ui->editDir->text());
    QStringList strList=dir.entryList(QDir::Files);

    ui->plainTextEdit->appendPlainText("所选目录下的所有文件:");
    for(int i=0;i<strList.count();i++)
        ui->plainTextEdit->appendPlainText(strList.at(i));
    ui->plainTextEdit->appendPlainText("\n");
}

QTemporaryDir 和 QTemporaryFile

QTemporaryDir 是用于创建、删除临时目录的类,其主要函数如下:

| 函数原型 | 功能 |
| — | — |
| void setAutoRemove(bool b) | 设置为是否自动删除 |
| QString path() | 返回创建的零时目录名称 |
| bool remove() | 删除此零时目录及其下面所有文件 |

在系统临时目录,及 QDir::tempPath目录下创建一个临时目录,临时目录名称以 QCoreApplication::applicationName()为前缀,后加 6 个字符。零时目录可以设置为使用完后自动删除,即临时目录变量删除。

QTemporaryFile 是用于创建临时文件的类,临时文件保存在系统临时目录下。临时文件以 QCoreApplication::applicationName()函数设置为是否自动删除临时文件。QTemporaryFile::open()函数用于打开临时文件,只有打开临时文件,才实际创建了此文件。

QFileSystemWatcher 类

QFileSystemWatcher 是对目录文件进行监听的类。把某些目录或文件添加到 QFileSystemWatcher 对象的监听列表后,当目录下发生文件新建、删除等操作时就会发射 directoryChanged()信号,当监听的文件发生修改、重命名等操作时,会发射 fileChanged()信号。所以,这个类在进行目录或文件监听时起作用。

QFileSystemWatcher 的主要接口函数如下:

| 函数原型 | 功能 |
| — | — |
| bool addPath(QString& path) | 添加一个监听的目录或文件 |
| QStringList addPaths(QStringList& paths) | 添加需要监听的目录或文件列表 |
| QStringList directories() | 返回监听的目录列表 |
| QStringList files() | 返回监听的文件列表 |
| bool removePath(QString& path) | 移除监听的目录或文件 |
| QStringList removePaths(QStringList& paths) | 移除监听的目录或文件列表 |

为了测试 QFileSystemWatcher 的功能,在主窗口类中定义了 QFileSystemWatcher 类型的变量和两个信号的槽函数,定义如下:

private:
    QFileSystemWatcher  fileWatcher;
    void    showBtnInfo(QObject* btn);
public slots:
    void on_directoryChanged(const QString path);
    void on_fileChanged(const QString path);

两个槽函数仅是显示传递的参数,并显示提示文字,代码如下:

void Dialog::on_directoryChanged(const QString path)
{ //directoryChanged()信号的槽函数
    ui->plainTextEdit->appendPlainText(path);
    ui->plainTextEdit->appendPlainText("目录发生了变化\n");
}

void Dialog::on_fileChanged(const QString path)
{//fileChanged()信号的槽函数
    ui->plainTextEdit->appendPlainText(path);
    ui->plainTextEdit->appendPlainText("文件发生了变化\n");
}

QFileSystemWatcher 分组里“addPath()开始监听”和“removePath()停止监听”两个按钮的代码如下:

void Dialog::on_pushButton_46_clicked()
{//开始监听,addPath()
    showBtnInfo(sender());
    ui->plainTextEdit->appendPlainText("监听目录:"+ui->editDir->text()+"\n");
    fileWatcher.addPath(ui->editDir->text());//添加监听目录
    fileWatcher.addPath(ui->editFile->text());//添加监听文件

    QObject::connect(&fileWatcher,&QFileSystemWatcher::directoryChanged,
            this,&Dialog::on_directoryChanged); //directoryChanged
    QObject::connect(&fileWatcher,&QFileSystemWatcher::fileChanged,
            this,&Dialog::on_fileChanged); //fileChanged
}

void Dialog::on_pushButton_47_clicked()
{//停止监听,removePath()
    showBtnInfo(sender());
    ui->plainTextEdit->appendPlainText("停止监听目录:"+ui->editDir->text()+"\n");
    fileWatcher.removePath(ui->editDir->text());//
    fileWatcher.removePath(ui->editFile->text());//
    QObject::disconnect(&fileWatcher,&QFileSystemWatcher::directoryChanged,
            this,&Dialog::on_directoryChanged); //directoryChanged
    QObject::disconnect(&fileWatcher,&QFileSystemWatcher::fileChanged,
            this,&Dialog::on_fileChanged); //fileChanged
}

采用 addPath()函数添加目录和文件后,将信号和槽函数关联起来,开始监听。

停止监听时,用 removePath()函数移除监听的目录和文件,并用 disconnect()解除信号和槽的关联。