烟台智能建站模板,临沂网站设计建设,哈尔滨设计优化公司,商城系统公司0、引言 我们知道 C 和 C 都提供了文件读写的类库#xff0c;不过 Qt 也有一套自己的文件读写操作#xff1b;本文主要介绍 Qt 中进行文件读写操作的类 —— QFile。
1、QFileDialog 文件对话框 一般的桌面应用程序#xff0c;当我们想要打开一个文件时#xff0c;通常会弹…0、引言 我们知道 C 和 C 都提供了文件读写的类库不过 Qt 也有一套自己的文件读写操作本文主要介绍 Qt 中进行文件读写操作的类 —— QFile。
1、QFileDialog 文件对话框 一般的桌面应用程序当我们想要打开一个文件时通常会弹出一个文件对话框。在 Qt 中文件对话框使用 QFileDialog 类实现。 QFileDialog 类允许用户遍历文件系统以便选择一个或多个文件或目录。 最简单的创建 QFileDialog 的方法是使用静态函数
fileName QFileDialog::getOpenFileName(this,tr(Open Image), /home, tr(Image Files (*.png *.jpg *.bmp))); tr() 是 Qt 中的一个函数用于将字符串标记为可翻译的字符串。这个函数的作用是在运行时根据配置在 Qt Linguist 工具中的翻译将输入字符串翻译成适当的语言。 这意味着如果您的应用程序支持多种语言并且在 Qt Linguist 工具中配置了相应的翻译那么这些字符串将在运行时被翻译成用户选择的语言。 在上面的例子中我们使用静态方法创建了一个模态 QFileDialog什么是 模态对话框。该对话框初始显示 /home 目录中的内容并显示与字符串 Image files (*.png *.jpg *.bmp) 中给出的模式匹配的文件。文件对话框的父窗口设置为 this窗口标题设置为 Open Image。 如果你想要使用多个过滤器请用 两个分号 分隔每一个过滤器。例如
Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml) 如果您想要不使用任何文件过滤器请直接传递空字符串。或者传递
All Files (*) (了解更多...) 在上面的例子中我们可以尝试使用 QFileDialog 选择一个文件并将 fileName 打印到单行文本框最终实现效果类似于下图 2、QFile QFileDialog 只是帮助我们完成了获取文件的绝对路径什么是 绝对路径(以 Windows 系统为例)的工作接下来才是要进行文件读写的操作。在 Qt 中文件读写通常与 QFile 类相关。 有关 QFile 的用法还请读者参考 QFile 的官方文档这里笔者不再赘述。下面主要介绍 QFileDialog 类配合 QFile 类的使用案例 2.1、QFile 读操作 以下代码展示了 QFileDialog 类配合 QFile 类打开并读取一张图片文件我们在与 QPushButton::clicked 信号关联的槽函数中读取图片文件
//点击“打开”按钮弹出文件选择对话框
connect(ui-pushButton, QPushButton::clicked, this, [](){QString fileName QFileDialog::getOpenFileName(this,tr(Open Image), /home , tr(Image Files (*.png *.jpg *.bmp *.svg)));//将路径放到 LineEdit 中ui-lineEdit-setText(fileName);//使用文件的绝对路径实例化 QFileQFile file(fileName);//只读模式打开文件file.open(QIODevice::ReadOnly);//全部读取QByteArray bytes file.readAll();//生成 QImage 实例QImage image QImage::fromData(bytes);//生成 QPixmap 实例并显示在 QLabel 控件上ui-label-setPixmap(QPixmap::fromImage(image));//关闭文件file.close();
}); 使用 QFileDialog 配合 QFile我们可以做到在运行时选择并读取图片文件 此外我们还可以尝试使用 QFileDialog 配合 QFile 打开文本文件只需略微修改上面示例代码中的槽函数即可 在 Linux(Ubuntu) 下你可以使用如下命令创建文本文件 touch filename.txt 创建完成后在其中编辑一些字符保存后就可以使用如下命令查看该文本文件的字符编码格式 file filename.txt# 如果文本文件中只有英文字符则编码格式为 ASCII
# 如果带有中文字符则编码格式为 UTF-8 Unicode。 使用如下命令转换文本文件的字符编码格式参考链接 sudo iconv -f utf-8 -t gbk filename.txt GbkText.txt //点击“打开”按钮弹出文件选择对话框
connect(ui-pushButton, QPushButton::clicked, this, [](){QString fileName QFileDialog::getOpenFileName(this,tr(Open Text File), /home , tr(Text Files (*.txt)));//将路径放到 LineEdit 中ui-lineEdit-setText(fileName);//使用文件的绝对路径实例化 QFileQFile file(fileName);//只读模式打开文件file.open(QIODevice::ReadOnly);//全部读取QByteArray bytes file.readAll();//在 QLabel 文件上显示文本ui-label-setText(bytes);//关闭文件file.close();
}); 需要注意的是QLabel::SetText() 方法接受一个 QString 类型的参数而在上面的示例代码中我们传递了一个字节数组作为参数。 巧合的是QString 类提供了一个接受 QByteArray 类型的构造函数这意味着这里会发生一次隐式转换将 QByteArray 类型转换为 QString 类型。不过这个构造函数的转换将会使用 UTF-8 格式解码字符串。 这样的隐式转换可能会导致一些问题特别是当你的文本文件不是 UTF-8 格式编码时 两个文本文件内容一致但 GBK 字符编码格式文件会显示乱码 为了避免这样的问题我们可以尝试使用一些 Qt 中专门用于编码和解码文本的类比如 QTextCodec在 Qt 5.15 过后已经部分弃用和 QStringConverter 类或者使用流来读取文件使用流的时候默认情况下QTextStream 假设文件以 UTF-8 编码但这可以使用QTextStream::setEncoding() 来改变。 2.2、QFile 写操作 除了读操作我们还可以使用 QFileDialog 类配合 QFile 类打开并向文件中写入数据。下面是一个打开文本文件并向其中追加新的文本的示例同样略微修改上面示例代码中的槽函数即可
//点击“打开”按钮弹出文件选择对话框
connect(ui-pushButton, QPushButton::clicked, this, [](){QString fileName QFileDialog::getOpenFileName(this,tr(Open Text File), /home , tr(Text Files (*.txt)));//将路径放到 LineEdit 中ui-lineEdit-setText(fileName);//使用文件的绝对路径实例化 QFileQFile file(fileName);//以追加的模式打开文件file.open(QIODevice::Append);//写数据file.write(这是我写入的文本\n);//关闭文件file.close();//重新以只读方式打开文件file.open(QIODevice::ReadOnly);QByteArray data;//当没有到达文件末尾时while(!file.atEnd()){//按行读取data file.readLine();}ui-label-setText(data);//关闭文件file.close();
});
下面是运行效果 3、QFileInfo 文件信息 QFileInfo 提供了文件在文件系统中的名称和位置路径、访问权限以及是目录还是符号链接等信息还有文件的大小、最后修改/读取时间等信息。此外QFileInfo 也可以用来获取关于 Qt 资源的信息。 QFileInfo 可以指向具有相对或绝对文件路径的文件。绝对文件路径以目录分隔符 / 开头或在 Windows 上以驱动器规格开头。相对文件名以目录名或文件名开头并指定相对于当前工作目录的路径。绝对路径的一个例子是字符串 /tmp/quartz。相对路径可能看起来像 src/fatlib。可以使用函数 isRelative() 检查 QFileInfo 使用的是相对文件路径还是绝对文件路径。您可以调用 makeAbsolute() 函数将 QFileInfo 的相对路径转换为绝对路径。 ⚠️ 注意以冒号(:)开头的路径总是被认为是绝对路径因为它们表示一个 QResource。 QFileInfo 处理的文件是在构造函数中设置的或者后续使用 setFile() 设置。使用 exists() 查看文件是否存在并使用 size() 获取其大小。 文件的类型通过 isFile()、isDir() 和 isSymLink() 获得。symLinkTarget() 函数提供了符号链接指向的文件的名称。 在 Unix包括 macOS 和 iOS上该类中的属性获取器函数返回目标文件的时间和大小等属性而不是符号链接的时间和大小等属性这是因为 Unix 透明地处理符号链接。使用 QFile 打开符号链接可以有效地打开链接的目标。例如
#ifdef Q_OS_UNIXQFileInfo info1(/home/bob/bin/untabify);
info1.isSymLink(); // returns true
info1.absoluteFilePath(); // returns /home/bob/bin/untabify
info1.size(); // returns 56201
info1.symLinkTarget(); // returns /opt/pretty/bin/untabifyQFileInfo info2(info1.symLinkTarget());
info2.isSymLink(); // returns false
info2.absoluteFilePath(); // returns /opt/pretty/bin/untabify
info2.size(); // returns 56201#endif 在 Windows 上快捷方式.lnk 文件目前被视为符号链接。与 Unix 系统一样属性获取器返回目标文件的大小而不是 .lnk 文件本身。此行为已被弃用可能会在 Qt 的未来版本中删除之后 .lnk 文件将被视为常规文件。
#ifdef Q_OS_WINQFileInfo info1(C:\\Users\\Bob\\untabify.lnk);
info1.isSymLink(); // returns true
info1.absoluteFilePath(); // returns C:/Users/Bob/untabify.lnk
info1.size(); // returns 63942
info1.symLinkTarget(); // returns C:/Pretty/untabifyQFileInfo info2(info1.symLinkTarget());
info2.isSymLink(); // returns false
info2.absoluteFilePath(); // returns C:/Pretty/untabify
info2.size(); // returns 63942#endif 文件名称的元素可以使用 path() 和 fileName() 提取。fileName() 的部分可以用 baseName()、suffix() 或 completeSuffix() 提取。QFileInfo 对象到由 Qt 类创建的目录将不会有尾随文件分隔符。如果您希望在自己的文件信息对象中使用尾随分隔符只需在构造函数或 setFile() 给出的文件名后附加一个。 文件的日期由 birthTime()、lastModified()、lastRead() 和 fileTime() 返回。通过 isReadable()、isWritable() 和 isExecutable() 获取文件的访问权限信息。文件的所有权可以从 owner()、ownerId()、group() 和 groupId() 中获得。您可以使用 permission() 函数在单个语句中检查文件的权限和所有权。 ⚠️ 注意在 NTFS 文件系统上出于性能原因默认情况下禁用所有权和权限检查。要启用它包括以下行 extern Q_CORE_EXPORT int qt_ntfs_permission_lookup;
然后通过对 qt_ntfs_permission_lookup 加 1 和减 1 来打开和关闭权限检查。
qt_ntfs_permission_lookup; //启用检查
qt_ntfs_permission_lookup--; //再次关闭检查 ⚠️ 注意由于这是一个非原子全局变量所以只有在除主线程以外的任何线程启动之前或除主线程以外的每个线程结束之后才可以对 qt_ntfs_permission_lookup 进行递增或递减操作。 下面是一个 QFileDialog 类配合 QFileInfo 类获取文件信息的代码示例同样略微修改 2.1 小节示例代码中的槽函数即可
//点击“打开”按钮弹出文件选择对话框
connect(ui-pushButton, QPushButton::clicked, this, [](){QString fileName QFileDialog::getOpenFileName(this,tr(Open File), /home, tr(All Files (*)));//将路径放到 LineEdit 中ui-lineEdit-setText(fileName);QFileInfo info(fileName);QString str path() info.path() \n filePath() info.filePath() \n fileName() info.fileName() \n baseName() info.baseName() \n suffix() info.suffix() \n completeSuffix() info.completeSuffix() \n birthTime() info.birthTime().toString(); //toString()方法可指定日期输出格式ui-label-setText(str);
}); 在打印文件的日期信息时可以指定输出的格式比如 info.birthTime().toString(yyyy/MM/dd hh:mm:ss); // 2023/08/16 21:12:34 参考 QDateTime 的 toString() 方法了解更多 运行效果