Qt类 | QFile类详解

一、QFile类介绍

  QFile 类提供了一个用于从文件读取和写入文件的接口。QFile 是 Qt 中用于文件 I/O 的类,支持读取和写入文本和二进制文件。可以单独使用,也可以与 QTextStreamQDataStream 结合使用。

QFile类使用要点

  • 文件名

    文件名通常在构造函数中指定,也可以通过 setFileName() 方法设置

  • 文件分隔符

    QFile 期望使用 ‘/’ 作为文件分隔符,不支持其他分隔符(例如 ‘\’)。

  • 文件操作

    • 使用 exists() 检查文件是否存在,使用 remove() 删除文件。
    • 使用 open() 打开文件,close() 关闭文件,flush() 刷新文件。
    • 读取和写入数据通常通过 QDataStreamQTextStream,也可以使用继承自 QIODeviceread(), readLine(), readAll(), write() 方法。
  • 文件位置和大小

    • 使用 size() 获取文件大小,pos() 获取当前文件位置,seek() 移动到新文件位置。
    • 使用 atEnd() 检查是否到达文件末尾。
  • 文件名编码转换

    • 使用 QFile, QFileInfo 和 QDir 访问文件系统时,可以使用 Unicode 文件名

    • 使用 encodeName() 和 decodeName() 函数在 Unicode 文件名和 8 位编码文件名之间进行转换。

  • QFile 不会发出 aboutToClose(), bytesWritten(), readyRead() 等信号,因此不适合用于读取和写入某些类型的文件,如 Unix 平台上的设备文件。

  • 文件权限在 Unix 类型系统和 Windows 上的处理方式不同。

逐行读取文本文件

 QFile file("in.txt");
 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
     return;

 while (!file.atEnd()) {
     QByteArray line = file.readLine();
     process_line(line);
 }
  • 默认情况下,QFile 假设二进制,即不对文件中存储的字节进行任何转换。
  • QIODevice::Text 标志告诉 Qt 将 Windows 风格的行终止符 (“\r\n”) 转换为 C++ 风格的终止符 (“\n”)。

使用QTextStream 流逐行读取文本文件

 QFile file("in.txt");
 if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
     return;

 QTextStream in(&file);
 while (!in.atEnd()) {
     QString line = in.readLine();
     process_line(line);
 }
  • QTextStream负责将存储在磁盘上的 8 位数据转换为 16 位 Unicode QString

使用QTextStream 流写入文件

 QFile file("out.txt");
 if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
     return;

 QTextStream out(&file);
 out << "The magic number is: " << 49 << "\n";
  • 使用 QTextStream 写入文本时,可以使用 << 操作符,可接受各种数据类型(包括QString)
  • QDataStreamQTextStream类似,使用 operator<<() 写入数据并使用 operator>>() 读取

二、Public Types(公共成员类型)

  • QFile::DecoderFn

    • 类型说明:

      QFile::DecoderFn 定义了一个函数指针,指向一个接受 QByteArray 类型参数并返回 QString 类型的函数,这个函数用于解码文件名,如:

      QString myDecoderFunc(const QByteArray &localFileName);
      

      可以使用 setDecodingFunction() 函数来设置一个解码函数,用于处理文件名的解码任务。

    • 示例:

      QString myDecoderFunc(const QByteArray &localFileName) {
          // 这里可以添加解码逻辑
          return QString::fromLocal8Bit(localFileName);  //
      }
      
      QFile file;
      file.setDecodingFunction(myDecoderFunc);
      

三、Public Functions(公共成员函数)

1.构造对象

QFile::QFile(const QString &name, QObject *parent)
QFile::QFile(QObject *parent)
QFile::QFile(const QString &name)
QFile::QFile()
  • 函数说明:
    • 带文件名和父对象的构造函数: 允许在创建文件对象时指定文件名和父对象。这使得文件对象可以被自动管理(例如,当父对象被销毁时,文件对象也会被销毁)。
    • 带父对象的构造函数: 只指定父对象,文件名可以在之后通过 setFileName() 方法设置。
    • 带文件名的构造函数: 只指定文件名,文件对象没有父对象。
    • 无参数的默认构造函数: 创建一个没有文件名和父对象的文件对象,文件名可以在之后通过 setFileName() 方法设置。
  • 注意事项:
    • 文件名可以在构造函数中指定,也可以在构造后通过 setFileName() 方法设置。
    • 文件操作通常需要检查操作是否成功(例如,使用 open() 方法返回的布尔值)。

2.open函数–打开文件

bool QFile::open(FILE *fh, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle)
  • 函数说明:

    打开一个现有的文件句柄,并根据指定的模式和标志进行操作。成功返回 true,失败返回 false

  • 参数说明:

    • FILE *fh:现有的文件句柄。

    • QIODevice::OpenMode mode:打开文件的模式。一般是OpenMode Flag 值的 OR 组合
      这个枚举类型与 open() 一起使用,以描述设备打开的模式。它也由 openMode() 返回。

      常量描述
      QIODevice::NotOpen0x0000设备未打开。
      QIODevice::ReadOnly0x0001设备以只读模式打开。
      QIODevice::WriteOnly0x0002设备以只写模式打开。注意,对于文件系统子类(例如 QFile),这种模式意味着截断,除非与 ReadOnly、Append 或 NewOnly 组合使用。
      QIODevice::ReadWriteReadOnly | WriteOnlyReadOnly | WriteOnly
      QIODevice::Append0x0004设备以追加模式打开,所有数据都写入文件末尾。
      QIODevice::Truncate0x0008如果可能,设备在打开前会被截断。设备的早期内容将丢失。
      QIODevice::Text0x0010读取时,行结束符被转换为 ‘\n’。写入时,行结束符被转换为本地编码,例如 Win32 中的 ‘\r\n’。
      QIODevice::Unbuffered0x0020绕过设备中的任何缓冲区。
      QIODevice::NewOnly0x0040如果要打开的文件已存在,则失败。仅在文件不存在时创建并打开文件。操作系统保证你是唯一一个创建和打开文件的。注意,这种模式意味着只写,并且允许与 ReadWrite 组合使用。这个标志目前只影响 QFile。将来其他类可能会使用这个标志,但在此之前,使用这个标志与任何非 QFile 的类可能会导致未定义的行为。(自 Qt 5.11 起)
      QIODevice::ExistingOnly0x0080如果要打开的文件不存在,则失败。这个标志必须与 ReadOnly、WriteOnly 或 ReadWrite 一起指定。注意,单独使用这个标志与 ReadOnly 是多余的,因为 ReadOnly 在文件不存在时已经会失败。这个标志目前只影响 QFile。将来其他类可能会使用这个标志,但在此之前,使用这个标志与任何非 QFile 的类可能会导致未定义的行为。(自 Qt 5.11 起)
    • QFileDevice::FileHandleFlags handleFlags:文件句柄标志,默认为 DontCloseHandle

      • 如果在 handleFlags 中指定了 AutoCloseHandle,则调用 close() 会关闭文件描述符。
      • 如果没有指定 AutoCloseHandle,则 close() 只会刷新文件,不会关闭文件描述符。
  • 示例:

    #include <stdio.h>
    
    void printError(const char* msg)
    {
         QFile file;
         file.open(stderr, QIODevice::WriteOnly);
         file.write(msg, qstrlen(msg));        // write to stderr
         file.close();
    }
    
bool QFile::open(int fd, QIODevice::OpenMode mode, QFileDevice::FileHandleFlags handleFlags = DontCloseHandle)
  • 函数说明:

    用于以特定的模式打开一个文件描述符,这个重载函数允许直接使用文件描述符而不是文件名来打开文件。成功打开文件时返回 true,否则返回 false

  • 参数说明:

    • fd(类型为 int):要打开的文件描述符。
    • mode(类型为 QIODevice::OpenMode):文件打开的模式,如只读、只写、读写等。
    • handleFlags:用于指定额外选项的标志。
      • 如果在 handleFlags 中指定了 AutoCloseHandle,则调用 close() 会关闭文件描述符。
      • 如果没有指定 AutoCloseHandle,则 close() 只会刷新文件,不会关闭文件描述符。
  • 示例:

    int fd = open("example.txt", O_RDONLY);
    
    // 创建 QFile 对象并打开文件描述符
    QFile file;
    if (file.open(fd, QIODevice::ReadOnly)) {
        // 读取文件内容
        QByteArray content = file.readAll();
        qDebug() << "File content:" << content;
    
        // 关闭文件
        file.close();
    } else {
        qDebug() << "Failed to open file";
    }
    
    // 关闭文件描述符
    close(fd);
    
  • 注意事项:

    • 如果文件描述符不是指向常规文件(例如标准输入-0、标准输出-1或标准错误-2),则可能无法进行 seek() 操作。

3.fileName/setFileName函数–获取/设置当前 QFile对象关联的文件名

[override virtual] QString QFile::fileName() const
void QFile::setFileName(const QString &name)
  • 函数说明:

    用于设置文件的名称。这个名称可以是文件名、相对路径或绝对路径。

  • 示例:

    QFile file;
    QDir::setCurrent("/tmp");
    file.setFileName("readme.txt");
    QDir::setCurrent("/home");
    file.open(QIODevice::ReadOnly);   // opens "/home/readme.txt" under Unix
    
  • 注意事项:

    • 如果文件已经被打开,不应调用此函数。这是因为一旦文件被打开,其路径和名称通常就固定了,改变文件名可能会导致不一致的状态。
    • 如果文件名没有包含路径或只包含相对路径,那么在调用 open() 函数时,将使用应用程序的当前工作目录作为文件的路径。

4.exist函数–检查文件是否存在

[static] bool QFile::exists(const QString &fileName)
bool QFile::exists() const
  • 函数说明:

    • 第一个函数:

      它接受一个文件名(可以是绝对路径或相对路径)作为参数,并检查这个文件是否存在。

      • 如果文件存在,返回 true;如果文件不存在或出现错误(如权限问题),返回 false
      • 特别地,如果提供的文件名是一个符号链接,并且该符号链接指向的文件不存在,则该函数也会返回 false
    • 第二个函数:

      它检查通过 fileName() 获取的当前文件名对应的文件是否存在。如果该文件存在,返回 true;否则返回 false

  • 示例:

    // 检查文件是否存在
    QString fileName = "example.txt";
    if (QFile::exists(fileName)) {
        qDebug() << "File exists.";
    } else {
        qDebug() << "File does not exist.";
    }
    
    // 创建 QFile 对象并检查关联文件是否存在
    QFile file;
    file.setFileName(fileName);
    if (file.exists()) {
        qDebug() << "File associated with QFile object exists.";
    } else {
        qDebug() << "File associated with QFile object does not exist.";
    }
    

5.copy函数–复制源文件到目标文件

bool QFile::copy(const QString &newName)
[static] bool QFile::copy(const QString &fileName, const QString &newName)
  • 函数说明:

    用于将当前QFile对象关联的文件(通过fileName()获取)复制到一个新文件。如果复制成功,返回true;如果失败(例如目标文件已存在),返回false。复制前会关闭源文件,确保数据的一致性。

  • 参数说明:

    • fileName:源文件名
    • newName:目标文件名
  • 示例:

    QFile file("source.txt");
    QString newName = "destination.txt";
    
    // 使用成员函数复制文件
    if (file.copy(newName)) {
        qDebug() << "File copied successfully.";
    } else {
        qDebug() << "File copy failed.";
    }
    
    // 使用静态函数复制文件
    if (QFile::copy("source.txt", "destination2.txt")) {
        qDebug() << "File copied successfully using static function.";
    } else {
        qDebug() << "File copy failed using static function.";
    }
    
  • 注意事项:

    如果目标文件存在则不会覆盖

6.link函数–创建关联文件链接

bool QFile::link(const QString &linkName)
[static] bool QFile::link(const QString &fileName, const QString &linkName)
  • 函数说明:

    用于创建一个指向当前QFile对象关联文件(通过fileName()获取)的链接。链接的类型取决于操作系统的文件系统,例如在 Windows 上是快捷方式,在 Unix 上是符号链接。如果创建链接成功,返回true;如果失败(例如目标链接已存在),返回false

  • 参数说明:

    • fileName:文件名称
    • linkName:链接名称
  • 示例:

    QFile file("source.txt");
    QString linkName = "source_link.txt";
    
    // 使用成员函数创建链接
    if (file.link(linkName)) {
        qDebug() << "Link created successfully.";
    } else {
        qDebug() << "Failed to create link:" << file.errorString();
    }
    
    // 使用静态函数创建链接
    if (QFile::link("source.txt", "source_link2.txt")) {
        qDebug() << "Link created successfully using static function.";
    } else {
        qDebug() << "Failed to create link using static function:" << QFile::errorString();
    }
    
  • 注意事项:

    如果链接存在,则会创建失败

7.rename函数–重命名文件

bool QFile::rename(const QString &newName)
[static] bool QFile::rename(const QString &oldName, const QString &newName)
  • 函数说明:

    用于将当前QFile对象关联的文件(通过fileName()获取)重命名为newName。如果重命名成功,返回true;如果失败(例如目标文件名已存在),返回false。重命名操作会关闭文件,确保文件状态的一致性。

  • 参数说明:

    • oldName:原始文件名
    • newName:新文件名
  • 示例:

    QFile file("source.txt");
    QString newName = "destination.txt";
    
    // 使用成员函数重命名文件
    if (file.rename(newName)) {
        qDebug() << "File renamed successfully.";
    } else {
        qDebug() << "Failed to rename file:" << file.errorString();
    }
    
    // 使用静态函数重命名文件
    if (QFile::rename("source.txt", "destination2.txt")) {
        qDebug() << "File renamed successfully using static function.";
    } else {
        qDebug() << "Failed to rename file using static function:" << QFile::errorString();
    }
    

8.moveToTrash函数–移动文件到垃圾箱

bool QFile::moveToTrash()
[static] bool QFile::moveToTrash(const QString &fileName, QString *pathInTrash = nullptr)
  • 函数说明:

    用于将当前QFile对象关联的文件(通过fileName()获取)移动到垃圾箱。如果移动成功,返回true,并更新fileName()为文件在垃圾箱中的路径。如果移动失败,返回false

  • 参数说明:

    • fileName:文件名
    • pathInTrash:文件在垃圾箱中的路径
  • 示例:

    QFile file("example.txt");
    
    // 使用成员函数移动文件到垃圾箱
    if (file.moveToTrash()) {
        qDebug() << "File moved to trash successfully. New path:" << file.fileName();
    } else {
        qDebug() << "Failed to move file to trash.";
    }
    
    // 使用静态函数移动文件到垃圾箱
    if (QFile::moveToTrash("example.txt", &pathInTrash)) {
        qDebug() << "File moved to trash successfully. Path in trash:" << pathInTrash;
    } else {
        qDebug() << "Failed to move file to trash.";
    }
    

9.remove函数–删除文件

bool QFile::remove()
[static] bool QFile::remove(const QString &fileName)
  • 函数说明:

    删除由 fileName() 指定的文件。如果成功返回 true;否则返回 false。在删除文件之前会关闭该文件。

  • 参数说明:

    • fileName:指定要删除的文件名
  • 示例:

    // 创建一个 QFile 对象并设置文件名
    QFile file("example.txt");
    
    // 检查文件是否存在
    if (file.exists()) {
        // 调用 remove() 成员函数删除文件
        bool success = file.remove();
        if (success) {
            qDebug() << "File removed successfully.";
        } else {
            qDebug() << "Failed to remove the file.";
        }
    } else {
        qDebug() << "File does not exist.";
    }
    
    // 使用静态 remove() 函数删除文件
    success = QFile::remove("example.txt");
    if (success) {
        qDebug() << "File removed successfully using static function.";
    } else {
        qDebug() << "Failed to remove the file using static function.";
    }
    

10.symLinkTarget函数–符号链接所指向文件或目录的绝对路径

QString QFile::symLinkTarget() const
[static] QString QFile::symLinkTarget(const QString &fileName)
  • 函数说明:

    返回由 fileName 指定的符号链接所指向的文件或目录的绝对路径,如果 fileName 不对应于一个符号链接,则返回一个空字符串。

  • 参数说明:

    • fileName:符号链接名称
  • 示例:

    // 定义符号链接的文件名
    QString linkName = "link.txt";
    
    // 使用静态函数获取符号链接的目标路径
    QString targetPath = QFile::symLinkTarget(linkName);
    if (targetPath.isEmpty()) {
        qDebug() << "The file is not a symbolic link or does not exist.";
    } else {
        qDebug() << "Symbolic link points to:" << targetPath;
    }
    
    // 检查符号链接指向的文件是否存在
    if (QFile::exists(targetPath)) {
        qDebug() << "The file pointed by the symbolic link exists.";
    } else {
        qDebug() << "The file pointed by the symbolic link does not exist.";
    }
    

四、Reimplemented Public Functions(重新实现的公共函数)

1.fileName函数–获取文件名称

[override virtual] QString QFile::fileName() const
  • 函数说明:

    这个函数重写自QFileDevice::fileName()

    返回通过 setFileName() 设置的名称,或者返回给 QFile 构造函数的名称。

2.open函数–打开文件

[override virtual] bool QFile::open(QIODevice::OpenMode mode)
  • 函数说明:

    这个函数重写自 QIODevice::open(QIODevice::OpenMode mode)

    使用指定模式打开文件,如果成功返回 true;否则返回 false。如果在只写或读写模式下打开文件,并且文件不存在,函数将尝试首先创建文件,然后再打开它。

  • 示例:

    // 创建 QFile 对象并设置文件名
    QFile file("example.txt");
    
    // 指定打开模式为读写模式
    QIODevice::OpenMode mode = QIODevice::ReadWrite;
    
    // 尝试打开文件
    if (file.open(mode)) {
        qDebug() << "File opened successfully.";
    
        // 进行文件读写操作...
    
        // 关闭文件
        file.close();
    } else {
        qDebug() << "Failed to open the file.";
    }
    

3.permissions函数–获取文件权限

[override virtual] QFileDevice::Permissions QFile::permissions() const
  • 函数说明:

    这个函数重写自QFileDevice::permissions。用于获取文件权限

4.setPermissions函数–修改文件权限

[override virtual] bool QFile::setPermissions(QFileDevice::Permissions permissions)
  • 函数说明:

    这个函数重写自QFileDevice::setPermissions(QFileDevice::Permissions permissions)

    将文件的权限设置为指定的权限。如果成功返回 true,如果权限无法修改则返回 false

  • 示例:

    // 设置文件为只读权限
    QFileDevice::Permissions permissions = QFileDevice::ReadUser;
    bool result = file.setPermissions(permissions);
    if (result) {
        qDebug() << "Permissions set successfully";
    } else {
        qDebug() << "Failed to set permissions";
    }
    

4.resize函数–调整文件的大小

[override virtual] bool QFile::resize(qint64 sz)
  • 函数说明:

    这个函数重写自QFileDevice::resize(qint64 sz)。成功调整文件大小时返回 true,否则返回 false

  • 参数说明:

    • sz(类型为 qint64):新的大小,单位是字节。如果这个值小于当前文件的大小,文件将被截断;如果大于当前大小,文件将被扩展,新扩展的部分通常填充为零。

5.size函数–获取文件大小

[override virtual] qint64 QFile::size() const
  • 函数说明:

    这个函数重写自:QFileDevice::size() const。 返回文件的大小,以字节为单位。

  • 示例:

    QFile file("example.txt");
    
    // 打开文件以获取文件大小
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Failed to open file";
        return 1;
    }
    qint64 size = file.size();
    file.close();
    
    // 输出文件大小
    qDebug() << "File size:" << size << "bytes";
    
  • 注意事项:

    • 如果文件成功打开,size() 返回文件的字节数。
    • 如果文件未打开或遇到错误,返回值是未定义的。

五、Static Public Members(静态公共函数)

1.decodeName函数–文件名解码

[static] QString QFile::decodeName(const QByteArray &localFileName)
[static] QString QFile::decodeName(const char *localFileName)
  • 函数说明:
    • 第一个函数用于将本地编码的文件名(QByteArray类型)解码为Unicode字符串(QString类型)。
    • 第二个函数是decodeName的重载版本,接受一个const char *类型的本地文件名。

2.encodeName函数–文件名编码

[static] QByteArray QFile::encodeName(const QString &fileName)
  • 函数说明:

    这个函数用于将Unicode字符串(QString类型)编码为本地8位编码(QByteArray类型)。

  • 28
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值