目录
二. 文件和目录 (File and Directory Handling)
7、QFile/QDir/QTextStream/QBuffe区别及应用场景
四. 多线程和并发 (Multithreading and Concurrency)
五. 国际化和本地化 (Internationalization and Localization)
六. 进程和进程间通信 (Process and Inter-Process Communication - IPC)
九. 动态库加载 (Dynamic Library Loading)
一. 核心数据类型 (Core Datatypes)
请跳转前一章节,此处不再重复:QT核心模块QtCore功能详细说明,并给出测试代码(一)
二. 文件和目录 (File and Directory Handling)
在 Qt 框架中,文件和目录相关的操作主要由 QFile、QDir、QFileInfo 等类提供支持。它们用于处理文件的读写、目录的创建和管理、文件路径解析等功能。
1、QFile
QFile
类是 Qt 框架中用于处理本地文件的核心类。它提供了一个平台无关的接口,用于文件的打开、读取、写入和关闭操作,并支持文本和二进制两种模式。
打开文件:
使用 open() 函数,需指定 OpenMode 枚举类型,open() 返回 true 表示成功,否则返回 false。常用标志包括:
- QIODevice::ReadOnly:只读模式。
- QIODevice::WriteOnly:只写模式(存在则覆盖,不存在则创建)。
- QIODevice::Append:追加模式(写入数据到文件末尾,不存在则创建)。
- QIODevice::ReadWrite:读写模式。
- QIODevice::Text:文本模式,处理行结束符转换。
- QIODevice::Truncate:以写入或读写模式打开时,若文件存在则截断为零长度。
- QIODevice::Unbuffered:禁用缓冲,直接读写磁盘。
打开模式标志 | 描述 |
---|---|
QIODevice::ReadOnly | 只读模式。 |
QIODevice::WriteOnly | 只写模式(存在则覆盖,不存在则创建)。 |
QIODevice::Append | 追加模式(写入数据到文件末尾,不存在则创建)。 |
QIODevice::ReadWrite | 读写模式。 |
QIODevice::Text | 文本模式,处理行结束符转换。 |
QIODevice::Truncate | 以写入或读写模式打开时,若文件存在则截断为零长度。 |
QIODevice::Unbuffered | 禁用缓冲,直接读写磁盘。 |
关闭文件:
-
使用 close() 函数关闭文件,确保数据正确写入磁盘并释放系统资源。
读取数据:
-
文本模式:
-
readLine():读取一行文本,包括行结束符,返回 QByteArray。
-
readAll():读取所有剩余内容,返回 QByteArray,通常转换为 QString。
-
可使用 QTextStream 类进行更方便的文本读取,提供格式化读取等功能。
-
-
二进制模式(不指定 Text):
-
read(qint64 maxSize):读取最多 maxSize 字节,返回 QByteArray。
-
readAll():读取所有剩余内容,返回 QByteArray。
-
readData(char *data, qint64 maxSize):尝试读取最多 maxSize 字节到 data 中,返回实际读取字节数。
-
模式 / 方法 | 描述 |
---|---|
文本模式 | |
readLine() | 读取一行文本,包括行结束符,返回QByteArray。 |
readAll() | 读取所有剩余内容,返回QByteArray,通常转换为QString。 |
QTextStream类 | 可用于更方便的文本读取,提供格式化读取等功能。 |
二进制模式(不指定 Text) | |
read(qint64 maxSize) | 读取最多maxSize字节,返回QByteArray。 |
readAll() | 读取所有剩余内容,返回QByteArray。 |
readData(char *data, qint64 maxSize) | 尝试读取最多maxSize字节到data中,返回实际读取字节数。 |
写入数据:
-
文本模式:
-
write(const QString &text):将 QString 写入文件。
-
write(const QByteArray &data):将 QByteArray 写入文件。
-
可使用 QTextStream 类进行格式化写入。
-
-
二进制模式(不指定 Text):
-
write(const QByteArray &data):将 QByteArray 写入文件。
-
writeData(const char *data, qint64 len):尝试写入 len 字节的数据,返回实际写入字节数。
-
模式 / 方法 | 描述 |
---|---|
文本模式 | |
write(const QString &text) | 将QString写入文件。 |
write(const QByteArray &data) | 将QByteArray写入文件。 |
QTextStream类 | 可用于格式化写入。 |
二进制模式(不指定 Text) | |
write(const QByteArray &data) | 将QByteArray写入文件。 |
writeData(const char *data, qint64 len) | 尝试写入len字节的数据,返回实际写入字节数。 |
检查文件状态:
-
exists(const QString &filename)(静态):检查指定路径的文件是否存在。
-
exists()(非静态):检查与 QFile 对象关联的文件是否存在。
-
isOpen():返回文件是否已打开。
-
isReadable():返回文件是否可读。
-
isWritable():返回文件是否可写。
错误处理:
-
error():返回最后一次文件操作的错误类型。
-
errorString():返回描述最后一次文件操作错误的字符串。
完整测试代码:
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QDebug>
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
// 定义测试文件路径
const QString filePath = "testfile.txt";
// ======================
// [1] 检查文件是否存在并删除
// ======================
if (QFile::exists(filePath)) {
qDebug() << "File exists, removing it first.";
QFile::remove(filePath); // 如果文件存在,先删除它
}
// ======================
// [2] 以文本写模式打开并写入
// ======================
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Failed to open for writing:" << file.errorString();
return 1; // 如果打开失败,返回错误码
}
QTextStream out(&file);
out << "Hello, Qt!\n"; // 写入第一行文本
out << "Line 2.\n"; // 写入第二行文本
file.close(); // 写入完成后关闭文件
qDebug() << "Text data written and file closed.";
// ======================
// [3] 以文本读模式打开并读取
// ======================
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "Failed to open for reading:" << file.errorString();
return 1; // 如果打开失败,返回错误码
}
QTextStream in(&file);
qDebug() << "Read line:" << in.readLine(); // 读取第一行
qDebug() << "Read all:" << in.readAll(); // 读取剩余内容
file.close(); // 读取完成后关闭文件
// ======================
// [4] 以追加模式打开并追加
// ======================
if (!file.open(QIODevice::Append | QIODevice::Text)) {
qDebug() << "Failed to open for appending:" << file.errorString();
return 1; // 如果打开失败,返回错误码
}
out.setDevice(&file);
out << "Appended line.\n"; // 追加一行文本
file.close(); // 追加完成后关闭文件
qDebug() << "Data appended and file closed.";
// ======================
// [5] 以二进制写模式打开并写入
// ======================
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Failed to open for binary writing:" << file.errorString();
return 1; // 如果打开失败,返回错误码
}
QByteArray binaryData = "Binary: \x01\x02\x03"; // 准备二进制数据
file.write(binaryData); // 写入二进制数据
file.close(); // 写入完成后关闭文件
qDebug() << "Binary data written and file closed.";
// ======================
// [6] 以二进制读模式打开并读取
// ======================
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open for binary reading:" << file.errorString();
return 1; // 如果打开失败,返回错误码
}
QByteArray readBinary = file.readAll(); // 读取所有二进制数据
qDebug() << "Read binary data:" << readBinary; // 输出二进制数据
file.close(); // 读取完成后关闭文件
// ======================
// [7] 检查文件状态
// ======================
qDebug() << "File exists:" << file.exists(); // 检查文件是否存在
qDebug() << "File is open:" << file.isOpen(); // 检查文件是否打开
qDebug() << "File is readable:" << file.isReadable(); // 检查文件是否可读
qDebug() << "File is writeable:" << file.isWritable(); // 检查文件是否可写
// ======================
// [8] 模拟错误:尝试打开不存在的文件
// ======================
QFile nonExistent("nonexistent.txt");
if (!nonExistent.open(QIODevice::ReadOnly)) {
qDebug() << "Error:" << nonExistent.error() << nonExistent.errorString(); // 输出错误信息
}
// ======================
// [9] 清理:删除测试文件
// ======================
if (file.exists()) {
file.remove(); // 删除测试文件
qDebug() << "Test file removed.";
}
return 0; // 程序正常结束
}
// ======================
// console
// ======================
//Text data written and file closed.
//Read line: "Hello, Qt!"
//Read all: "Line 2.\n"
//Data appended and file closed.
//Binary data written and file closed.
//Read binary data: "Binary: \x01\x02\x03"
//File exists: true
//File is open: false
//File is readable: false
//File is writeable: false
//Error: 5 "No such file or directory"
//Test file removed.
2、QDir
QDir
类提供了对文件系统目录的操作,如列出目录内容、创建目录和删除目录等。
构造和路径管理:
-
构造函数:
-
QDir(const QString &path):构造一个指向指定路径的 QDir 对象。如果路径为空,则使用当前工作目录(".")。
-
QDir():构造一个指向当前工作目录的 QDir 对象。
-
-
路径操作:
-
setPath(const QString &path):设置 QDir 的路径。
-
path():返回当前路径。
-
absolutePath():返回目录的绝对路径。
-
canonicalPath():返回规范化路径,解析符号链接,但如果路径不存在则返回空字符串。
-
dirName():返回目录名称(路径的最后一部分),例如QDir("/home/user/docs").dirName() 返回 "docs"。
-
isRelative() 和 isAbsolute():检查路径是相对路径还是绝对路径。
-
makeAbsolute():将相对路径转换为绝对路径。
-
目录导航:
-
cd(const QString &dirName):切换到指定子目录,返回 true 如果成功。
-
cdUp():切换到父目录,返回 true 如果成功。
-
QDir::setCurrent(const QString &path)(静态):设置应用程序的当前工作目录。
-
QDir::currentPath()(静态):返回当前工作目录。
目录操作:
-
mkdir(const QString &dirName):创建指定名称的子目录。
-
rmdir(const QString &dirName):删除指定名称的子目录。
-
mkpath(const QString &dirPath):创建指定路径的目录(包括父目录)。
-
rmpath(const QString &dirPath):删除指定路径的目录(包括子目录)。
-
rename(const QString &oldName, const QString &newName):重命名目录或文件。
列出目录内容:
-
entryList():返回目录中所有条目(文件和子目录)的名称列表。
-
entryInfoList():返回目录中所有条目的 QFileInfo 列表,包含更多信息(如大小、权限等)。
-
过滤和排序:
-
setFilter(QDir::Filters filters):设置过滤条件,例如:
-
QDir::Files:仅列出文件。
-
QDir::Dirs:仅列出目录。
-
QDir::NoSymLinks:不列出符号链接。
-
QDir::Hidden:列出隐藏文件。
-
QDir::Readable、QDir::Writable、QDir::Executable:列出具有相应权限的条目。
-
-
setSorting(QDir::SortFlags sort):设置排序方式,例如:
-
QDir::Name:按名称排序。
-
QDir::Size:按大小排序。
-
QDir::Time:按修改时间排序。
-
QDir::Reversed:反向排序。
-
-
setNameFilters(const QStringList &nameFilters):设置名称过滤器,支持通配符(如 "*.txt")。
-
方法 | 描述 |
---|---|
entryList() | 返回目录中所有条目(文件和子目录)的名称列表。 |
entryInfoList() | 返回目录中所有条目的 QFileInfo 列表,包含更多信息(如大小、权限等)。 |
过滤:setFilter(QDir::Filters filters) | |
设置过滤条件 | |
QDir::Files | 仅列出文件。 |
QDir::Dirs | 仅列出目录。 |
QDir::NoSymLinks | 不列出符号链接。 |
QDir::Hidden | 列出隐藏文件。 |
QDir::Readable | 列出具有可读权限的条目。 |
QDir::Writable | 列出具有可写权限的条目。 |
QDir::Executable | 列出具有可执行权限的条目。 |
排序:setSorting(QDir::SortFlags sort) | |
设置排序方式 | |
QDir::Name | 按名称排序。 |
QDir::Size | 按大小排序。 |
QDir::Time | 按修改时间排序。 |
QDir::Reversed | 反向排序。 |
检查目录状态:
-
exists():检查目录是否存在。
-
isReadable():检查目录是否可读。
-
isRoot():检查是否为根目录。
特殊路径:
-
QDir::homePath():返回用户主目录路径。
-
QDir::tempPath():返回临时目录路径。
-
QDir::rootPath():返回根目录路径。
-
QDir::drives():返回系统根目录列表(Windows 上为 "C:/"、"D:/" 等,Unix 上为 "/")。
路径转换:
-
toNativeSeparators(const QString &pathName)(静态):将路径中的分隔符转换为操作系统原生分隔符。
-
fromNativeSeparators(const QString &pathName)(静态):将路径中的分隔符转换为 "/"。
-
cleanPath(const QString &path)(静态):规范化路径,移除多余的 "."、".." 和分隔符。
注意事项
-
符号链接:QDir 默认保留符号链接,不会自动解析,除非使用 canonicalPath()。
-
Android 限制:在 Android 上,QDir 对内容 URI 的支持有限,cdUp() 不支持内容 URI。
-
性能:对于大型目录,建议使用 QDirIterator 逐个遍历条目,而不是一次性使用 entryList() 或 entryInfoList()。
完整测试代码
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QDebug>
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
// ======================
// [1] 创建测试目录
// ======================
QString testDirPath = "testDir/subDir";
QDir dir;
if (!dir.exists(testDirPath)) {
qDebug() << "Creating directory:" << testDirPath;
dir.mkpath(testDirPath); // 创建目录及其父目录
}
// ======================
// [2] 检查目录是否存在并输出绝对路径
// ======================
qDebug() << "Directory exists:" << dir.exists(testDirPath);
qDebug() << "Absolute path:" << QDir(testDirPath).absolutePath();
// ======================
// [3] 创建测试文件并写入数据
// ======================
QFile file(testDirPath + "/test.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out << "This is a test file.\n"; // 写入测试数据
file.close(); // 写入完成后关闭文件
}
// ======================
// [4] 列出目录内容
// ======================
QDir testDir(testDirPath);
testDir.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); // 过滤文件和目录
testDir.setSorting(QDir::Name); // 按名称排序
qDebug() << "\nListing directory contents in" << testDirPath << ":";
QStringList list = testDir.entryList(); // 获取目录内容列表
for (const QString &name : list) {
QFileInfo info(testDirPath + "/" + name);
qDebug() << (info.isDir() ? "Dir :" : "File:") << name; // 输出目录或文件信息
}
// ======================
// [5] 目录导航
// ======================
QDir currentDir = QDir::current();
qDebug() << "\nCurrent directory:" << currentDir.path(); // 输出当前目录
if (currentDir.cd(testDirPath)) {
qDebug() << "Changed to:" << currentDir.path(); // 切换到测试目录
if (currentDir.cdUp()) {
qDebug() << "Moved up to:" << currentDir.path(); // 返回上一级目录
}
}
// ======================
// [6] 重命名目录
// ======================
QDir parentDir("testDir");
if (parentDir.rename("subDir", "newSubDir")) {
qDebug() << "\nRenamed subDir to newSubDir"; // 重命名目录
}
// ======================
// [7] 特殊路径
// ======================
qDebug() << "\nSpecial paths:";
qDebug() << "Home path:" << QDir::homePath(); // 用户主目录路径
qDebug() << "Temp path:" << QDir::tempPath(); // 临时目录路径
qDebug() << "Root path:" << QDir::rootPath(); // 根目录路径
qDebug() << "Drives:" << QDir::drives().size() << "drives found"; // 驱动器数量
// ======================
// [8] 路径转换
// ======================
QString path = "testDir/newSubDir/test.txt";
qDebug() << "\nPath conversions:";
qDebug() << "To native separators:" << QDir::toNativeSeparators(path); // 转换为本地路径分隔符
qDebug() << "From native separators:" << QDir::fromNativeSeparators(path); // 从本地路径分隔符转换
qDebug() << "Cleaned path:" << QDir::cleanPath("../testDir/./newSubDir/../newSubDir/test.txt"); // 清理路径
// ======================
// [9] 删除目录
// ======================
QDir removeDir("testDir");
if (removeDir.exists()) {
qDebug() << "\nRemoving directory testDir";
removeDir.removeRecursively(); // 递归删除目录及其内容
}
qDebug() << "Directory exists after removal:" << removeDir.exists(); // 检查目录是否已删除
return 0; // 程序正常结束
}
// ======================
// console
// ======================
//Creating directory: "testDir/subDir"
//Directory exists: true
//Absolute path: "/home/user/QtProj/build-QtCore-Desktop-Debug/testDir/subDir"
//Listing directory contents in "testDir/subDir" :
//File: "test.txt"
//Current directory: "/home/user/QtProj/build-QtCore-Desktop-Debug"
//Changed to: "/home/user/QtProj/build-QtCore-Desktop-Debug/testDir/subDir"
//Moved up to: "/home/user/QtProj/build-QtCore-Desktop-Debug/testDir"
//Renamed subDir to newSubDir
//Special paths:
//Home path: "/home/user"
//Temp path: "/tmp"
//Root path: "/"
//Drives: 1 drives found
//Path conversions:
//To native separators: "testDir/newSubDir/test.txt"
//From native separators: "testDir/newSubDir/test.txt"
//Cleaned path: "../testDir/newSubDir/test.txt"
//Removing directory testDir
//Directory exists after removal: false
3、QFileInfo
用于检索文件系统条目(文件或目录)的元数据。支持隐式共享,所有方法可重入(reentrant),线程安全。主要功能包括:
-
获取文件路径、名称、大小、时间戳、权限等。
-
判断文件类型(如文件、目录、符号链接)。
构造函数
构造函数 | 描述 |
---|---|
QFileInfo() noexcept | 构造一个空的QFileInfo对象。 |
QFileInfo(const QString &file) | 基于文件路径构造对象,路径可为绝对或相对路径。 |
QFileInfo(const QFile &file) | 基于QFile对象构造。 |
QFileInfo(const QDir &dir, const QString &file) | 基于目录和相对路径构造。 |
QFileInfo(const QFileInfo &fileinfo) noexcept | 拷贝构造函数。 |
测试代码 - 构造函数
#include <QFileInfo>
#include <QFile>
#include <QDir>
#include <QDebug>
int main() {
// 空构造函数
QFileInfo info1;
qDebug() << "空构造函数:" << (info1.exists() ? "已设置" : "未设置");
// 路径构造函数
QFileInfo info2("/path/to/file.txt");
qDebug() << "路径构造函数:" << info2.filePath();
// QFile 构造函数
QFile file("test.txt");
QFileInfo info3(file);
qDebug() << "QFile 构造函数:" << info3.filePath();
// QDir 和相对路径构造函数
QDir dir("/home/user");
QFileInfo info4(dir, "docs/file.txt");
qDebug() << "QDir 构造函数:" << info4.filePath();
// 拷贝构造函数
QFileInfo info5(info2);
qDebug() << "拷贝构造函数:" << info5.filePath();
return 0;
}
// ======================
// console
// ======================
//空构造函数: 未设置
//路径构造函数: "/path/to/file.txt"
//QFile 构造函数: "test.txt"
//QDir 构造函数: "/home/user/docs/file.txt"
//拷贝构造函数: "/path/to/file.txt"
文件存在性与基本信息
方法 | 返回类型 | 描述 |
---|---|---|
bool exists() const | bool | 返回true如果文件或目录存在(符号链接检查目标)。 |
void refresh() | void | 刷新缓存,获取最新文件系统信息。 |
void setFile(const QString &file) | void | 设置新的文件路径。 |
void setFile(const QFile &file) | void | 基于QFile对象设置文件。 |
void setFile(const QDir &dir, const QString &file) | void | 基于目录和相对路径设置文件。 |
测试代码 - 文件存在性与基本信息
#include <QFileInfo>
#include <QFile>
#include <QDir>
#include <QDebug>
int main() {
QFileInfo info("test.txt");//created ./test.txt
qDebug() << "初始存在性:" << info.exists();
// 设置新路径并检查
info.setFile("/path/to/file.txt");
qDebug() << "设置路径后:" << info.exists();
// 使用 QFile 设置
QFile file("newfile.txt");//created ./newfile.txt
info.setFile(file);
qDebug() << "使用 QFile 设置:" << info.exists();
// 使用 QDir 设置
QDir dir("/home/user");
info.setFile(dir, "docs/test.txt");
qDebug() << "使用 QDir 设置:" << info.exists();
// 刷新信息
info.refresh();
qDebug() << "刷新后存在性:" << info.exists();
return 0;
}
// ======================
// console
// ======================
//初始存在性: true
//设置路径后: false
//使用 QFile 设置: true
//使用 QDir 设置: false
//刷新后存在性: false
文件路径相关
方法 | 返回类型 | 描述 |
---|---|---|
QString absoluteFilePath() const | QString | 返回绝对路径(含文件名)。 |
QString absolutePath() const | QString | 返回目录的绝对路径(不含文件名)。 |
QString canonicalFilePath() const | QString | 返回规范路径(无符号链接,若不存在返回空字符串)。 |
QString canonicalPath() const | QString | 返回目录的规范路径。 |
QString fileName() const | QString | 返回文件名(含扩展名)。 |
QString filePath() const | QString | 返回完整路径(可能是相对或绝对路径)。 |
QString path() const | QString | 返回目录路径(可能是相对或绝对路径)。 |
bool isAbsolute() const | bool | 返回true如果路径是绝对路径。 |
bool isRelative() const | bool | 返回true如果路径是相对路径。 |
bool makeAbsolute() | bool | 将相对路径转换为绝对路径,返回true如果成功。 |
测试代码 - 文件路径相关
#include <QFileInfo>
#include <QDebug>
int main() {
QFileInfo info("docs/test.txt");
qDebug() << "文件名:" << info.fileName();
qDebug() << "完整路径:" << info.filePath();
qDebug() << "目录路径:" << info.path();
qDebug() << "绝对路径:" << info.absoluteFilePath();
qDebug() << "绝对目录:" << info.absolutePath();
qDebug() << "规范路径:" << info.canonicalFilePath();
qDebug() << "规范目录:" << info.canonicalPath();
qDebug() << "是否绝对路径:" << info.isAbsolute();
qDebug() << "是否相对路径:" << info.isRelative();
// 转换为绝对路径
if (info.makeAbsolute()) {
qDebug() << "转换后绝对路径:" << info.filePath();
}
return 0;
}
// ======================
// console
// ======================
//文件名: "test.txt"
//完整路径: "docs/test.txt"
//目录路径: "docs"
//绝对路径: "/home/user/QtProj/QtCore/docs/test.txt"
//绝对目录: "/home/user/QtProj/QtCore/docs"
//规范路径: ""
//规范目录: "."
//是否绝对路径: false
//是否相对路径: true
//转换后绝对路径: "/home/user/QtProj/QtCore/docs/test.txt"
文件名分解
方法 | 返回类型 | 描述 |
---|---|---|
QString baseName() const | QString | 返回基本名称(不含路径和扩展名,第一个.前)。 |
QString completeBaseName() const | QString | 返回完整基本名称(不含路径,直到最后一个.前)。 |
QString suffix() const | QString | 返回扩展名(最后一个.后)。 |
QString completeSuffix() const | QString | 返回完整扩展名(第一个.后所有部分)。 |
测试代码 - 文件名分解
#include <QFileInfo>
#include <QDebug>
int main() {
QFileInfo info("/path/to/file.tar.gz");
qDebug() << "基本名称:" << info.baseName(); // "file"
qDebug() << "完整基本名称:" << info.completeBaseName(); // "file.tar"
qDebug() << "扩展名:" << info.suffix(); // "gz"
qDebug() << "完整扩展名:" << info.completeSuffix(); // "tar.gz"
return 0;
}
// ======================
// console
// ======================
//基本名称: "file"
//完整基本名称: "file.tar"
//扩展名: "gz"
//完整扩展名: "tar.gz"
文件类型检查
方法 | 返回类型 | 描述 |
---|---|---|
bool isBundle() const | bool | 返回true如果是 macOS/iOS 捆绑包或其符号链接。 |
bool isDir() const | bool | 返回true如果是目录或指向目录的符号链接。 |
bool isFile() const | bool | 返回true如果是普通文件或指向普通文件的符号链接。 |
bool isSymLink() const | bool | 返回true如果是符号链接(包括 Windows .lnk 和 macOS 别名)。 |
bool isSymbolicLink() const | bool | 返回true如果是符号链接(不包括快捷方式和别名,Qt 6.4+)。 |
bool isShortcut() const | bool | 返回true如果是 Windows 快捷方式 (.lnk)。 |
bool isAlias() const | bool | 返回true如果是 macOS 别名(Qt 6.8+)。 |
QString symLinkTarget() const | QString | 返回符号链接的目标路径。 |
测试代码 - 文件类型检查
#include <QFileInfo>
#include <QDebug>
int main() {
QFileInfo info("/path/to/file.txt");
qDebug() << "是文件:" << info.isFile();
qDebug() << "是目录:" << info.isDir();
qDebug() << "是符号链接:" << info.isSymLink();
if (info.isSymLink()) {
qDebug() << "链接目标:" << info.symLinkTarget();
}
qDebug() << "是纯符号链接:" << info.isSymbolicLink();
qDebug() << "是快捷方式:" << info.isShortcut();
// qDebug() << "是别名:" << info.isAlias();
qDebug() << "是捆绑包:" << info.isBundle();
return 0;
}
// ======================
// console
// ======================
//是文件: false
//是目录: false
//是符号链接: false
//是纯符号链接: false
//是快捷方式: false
//是捆绑包: false
文件大小
方法 | 返回类型 | 描述 |
---|---|---|
qint64 size() const | qint64 | 返回文件大小(字节),不存在或无法获取返回 0,符号链接返回目标大小。 |
#include <QFileInfo>
#include <QDebug>
int main() {
QFileInfo info("/path/to/file.txt");
if (info.exists()) {
qDebug() << "文件大小:" << info.size() << "字节";
} else {
qDebug() << "文件不存在,大小:" << info.size();
}
return 0;
}
// ======================
// console
// ======================
//文件不存在,大小: 0
时间信息
方法 | 返回类型 | 描述 |
---|---|---|
QDateTime birthTime() const | QDateTime | 返回创建时间(本地时间),不可用返回无效值。 |
QDateTime lastModified() const | QDateTime | 返回最后修改时间(本地时间),符号链接返回目标时间。 |
QDateTime lastRead() const | QDateTime | 返回最后读取时间(本地时间),不可用可能与 lastModified() 相同。 |
QDateTime metadataChangeTime() const | QDateTime | 返回元数据最后更改时间(本地时间)。 |
QDateTime fileTime(QFileDevice::FileTime time) const | QDateTime | 返回指定类型时间(Qt 6.6+ 支持时区)。 |
测试代码 - 时间信息
#include <QFileInfo>
#include <QDebug>
#include <QDateTime>
int main() {
QFileInfo info("./test.txt");//created ./test.txt
if (info.exists()) {
qDebug() << "创建时间:" << info.birthTime().toString();
qDebug() << "最后修改:" << info.lastModified().toString();
qDebug() << "最后读取:" << info.lastRead().toString();
qDebug() << "元数据更改:" << info.metadataChangeTime().toString();
qDebug() << "创建时间(fileTime):" << info.fileTime(QFileDevice::FileBirthTime).toString();
} else {
qDebug() << "文件不存在";
}
return 0;
}
// ======================
// console
// ======================
//创建时间: "Fri Mar 28 19:25:00 2025"
//最后修改: "Fri Mar 28 19:25:00 2025"
//最后读取: "Fri Mar 28 19:25:00 2025"
//元数据更改: "Fri Mar 28 19:25:00 2025"
//创建时间(fileTime): "Fri Mar 28 19:25:00 2025"
权限与所有者
方法 | 返回类型 | 描述 |
---|---|---|
bool isReadable() const | bool | 返回true如果用户有读权限。 |
bool isWritable() const | bool | 返回true如果用户有写权限。 |
bool isExecutable() const | bool | 返回true如果文件可执行。 |
QFileDevice::Permissions permissions() const | QFileDevice::Permissions | 返回权限标志集合。 |
QString owner() const | QString | 返回所有者用户名(不可用返回空字符串)。 |
uint ownerId() const | uint | 返回所有者用户 ID(不可用返回 -2)。 |
QString group() const | QString | 返回所属组名称(不可用返回空字符串)。 |
uint groupId() const | uint | 返回所属组 ID(不可用返回 -2)。 |
测试代码 - 权限与所有者
#include <QFileInfo>
#include <QDebug>
int main() {
QFileInfo info("./test.txt");//created ./test.txt
if (info.exists()) {
qDebug() << "可读:" << info.isReadable();
qDebug() << "可写:" << info.isWritable();
qDebug() << "可执行:" << info.isExecutable();
qDebug() << "权限标志:" << QString::number(info.permissions(), 16);
qDebug() << "所有者:" << info.owner();
qDebug() << "所有者 ID:" << info.ownerId();
qDebug() << "组:" << info.group();
qDebug() << "组 ID:" << info.groupId();
} else {
qDebug() << "文件不存在";
}
return 0;
}
// ======================
// console
// ======================
//可读: true
//可写: true
//可执行: false
//权限标志: "6664"
//所有者: "user"
//所有者 ID: 1000
//组: "user"
//组 ID: 1000
缓存控制
方法 | 返回类型 | 描述 |
---|---|---|
void setCaching(bool enable) | void | 设置是否启用缓存(默认true)。 |
bool caching() const | bool | 返回是否启用缓存。 |
测试代码 - 缓存控制
#include <QFileInfo>
#include <QDebug>
int main() {
QFileInfo info("./test.txt");//created ./test.txt
qDebug() << "默认缓存状态:" << info.caching();
info.setCaching(false);
qDebug() << "禁用缓存后:" << info.caching();
info.setCaching(true);
qDebug() << "启用缓存后:" << info.caching();
return 0;
}
// ======================
// console
// ======================
//默认缓存状态: true
//禁用缓存后: false
//启用缓存后: true
其他
方法 | 返回类型 | 描述 |
---|---|---|
QDir absoluteDir() const | QDir | 返回文件所在目录的绝对路径的QDir对象。 |
QDir dir() const | QDir | 返回文件所在目录的QDir对象(可能是相对路径)。 |
bool isRoot() const | bool | 返回true如果是根目录(如 "/" 或 "C:/")。 |
bool isNativePath() const | bool | 返回true如果是本地文件系统路径(非 Qt 资源路径)。 |
测试代码 - 其他
#include <QFileInfo>
#include <QDir>
#include <QDebug>
int main() {
QFileInfo info("/path/to/file.txt");
qDebug() << "绝对目录:" << info.absoluteDir().path();
qDebug() << "目录:" << info.dir().path();
qDebug() << "是根目录:" << info.isRoot();
qDebug() << "是本地路径:" << info.isNativePath();
QFileInfo info2(":/resource.txt");
qDebug() << "资源路径是本地路径:" << info2.isNativePath();
return 0;
}
// ======================
// console
// ======================
//绝对目录: "/path/to"
//目录: "/path/to"
//是根目录: false
//是本地路径: true
//资源路径是本地路径: false
操作符
操作符 | 返回类型 | 描述 |
---|---|---|
QFileInfo &operator=(const QFileInfo &fileinfo) noexcept | QFileInfo & | 赋值操作符。 |
bool operator==(const QFileInfo &fileinfo) const | bool | 返回true如果指向相同文件系统条目。 |
bool operator!=(const QFileInfo &fileinfo) const | bool | 返回true如果指向不同文件系统条目。 |
测试代码 - 操作符
#include <QFileInfo>
#include <QDebug>
int main() {
QFileInfo info1("/path/to/file.txt");
QFileInfo info2(info1);
QFileInfo info3("/other/file.txt");
qDebug() << "info1 == info2:" << (info1 == info2);
qDebug() << "info1 != info3:" << (info1 != info3);
info3 = info1;
qDebug() << "赋值后 info3 == info1:" << (info3 == info1);
return 0;
}
// ======================
// console
// ======================
//info1 == info2: true
//info1 != info3: false
//赋值后 info3 == info1: true
静态方法
方法 | 返回类型 | 描述 |
---|---|---|
static bool exists(const QString &file) | bool | 返回true如果指定路径存在。 |
测试代码 - 静态方法
#include <QFileInfo>
#include <QDebug>
int main() {
qDebug() << "文件存在性:" << QFileInfo::exists("./test.txt");//created ./test.txt
qDebug() << "不存在文件:" << QFileInfo::exists("/nonexistent/file.txt");
return 0;
}
// ======================
// console
// ======================
//文件存在性: true
//不存在文件: false
注意事项
-
符号链接:Unix 系统方法返回目标信息,Windows 上 .lnk 文件视为符号链接。
-
缓存:默认启用,需用 refresh() 更新。
-
权限:Windows 非 NTFS 环境可能不准确。
-
路径:支持绝对/相对路径及 Qt 资源路径(如 ":/resource.txt")。
4、QTextStream
QTextStream 是 Qt Core 模块中的类,提供了一个方便的接口,用于从文本流中读取和写入文本。它支持多种设备(如 QFile、QString、QByteArray 等),并处理编码、换行符和格式化输出。QTextStream 是隐式共享类,所有方法可重入(reentrant),线程安全。主要功能包括:
-
从设备读取文本(逐行或全部)。
-
向设备写入格式化文本。
-
支持编码设置和数字格式化。
公共类型
类型名 | 描述 |
---|---|
FieldAlignment | 枚举类型,定义字段对齐方式(AlignLeft、AlignRight、AlignCenter、AlignAccountingStyle)。 |
NumberFlag | 枚举类型,定义数字格式标志(ShowBase、ForcePoint、ForceSign、UppercaseBase、UppercaseDigits)。组合使用NumberFlags。 |
RealNumberNotation | 枚举类型,定义实数表示法(SmartNotation、FixedNotation、ScientificNotation )。 |
Status | 枚举类型,定义流状态(Ok、ReadPastEnd、ReadCorruptedData、WriteFailed )。 |
构造函数
构造函数 | 描述 |
---|---|
QTextStream() | 构造一个未绑定设备的空 QTextStream 对象。 |
QTextStream(QIODevice *device) | 构造一个绑定到指定QIODevice 的QTextStream对象。 |
QTextStream(FILE *fileHandle, QIODevice::OpenMode openMode = QIODevice::ReadWrite) | 基于标准 C 文件句柄构造,支持指定打开模式。 |
QTextStream(QString *string, QIODevice::OpenMode openMode = QIODevice::ReadWrite) | 基于QString构造,用于读写字符串。 |
QTextStream(QByteArray *array, QIODevice::OpenMode openMode = QIODevice::ReadWrite) | 基于QByteArray构造,用于读写字节数组。 |
QTextStream(const QByteArray &array, QIODevice::OpenMode openMode = QIODevice::ReadOnly) | 基于只读QByteArray构造,仅支持读取。 |
测试代码 - 构造函数
#include <QTextStream>
#include <QFile>
#include <QString>
#include <QByteArray>
#include <QDebug>
int main() {
// 空构造函数
QTextStream stream1;
qDebug() << "空构造函数:" << (stream1.device() ? "已绑定" : "未绑定");
// QIODevice 构造函数
QFile file("test.txt");
file.open(QIODevice::WriteOnly);
QTextStream stream2(&file);
qDebug() << "QIODevice 构造函数:" << (stream2.device() == &file);
// FILE 构造函数
FILE *fh = fopen("test.txt", "w");
QTextStream stream3(fh);
qDebug() << "FILE 构造函数:" << (stream3.device() != nullptr);
fclose(fh);
// QString 构造函数
QString str;
QTextStream stream4(&str);
qDebug() << "QString 构造函数:" << (stream4.string() == &str);
// QByteArray 构造函数(读写)
QByteArray array;
QTextStream stream5(&array);
qDebug() << "QByteArray 读写构造函数:" << (stream5.device() != nullptr);
// QByteArray 只读构造函数
QByteArray data = "Hello";
QTextStream stream6(data);
qDebug() << "QByteArray 只读构造函数:" << (stream6.device() != nullptr);
return 0;
}
// ======================
// console
// ======================
//空构造函数: 未绑定
//QIODevice 构造函数: true
//FILE 构造函数: true
//QString 构造函数: true
//QByteArray 读写构造函数: true
//QByteArray 只读构造函数: true
析构函数
析构函数 | 描述 |
---|---|
~QTextStream() | 销毁对象,隐式共享类仅在最后一个引用销毁时释放数据。不会关闭底层设备。 |
设备与状态管理
方法 | 返回类型 | 描述 |
---|---|---|
QIODevice *device() const | QIODevice * | 返回当前绑定的设备指针,若未绑定返回nullptr。 |
void setDevice(QIODevice *device) | void | 设置绑定的设备,替换现有设备但不关闭原设备。 |
Status status() const | Status | 返回流的状态(Ok、ReadPastEnd、ReadCorruptedData、WriteFailed)。 |
void setStatus(Status status) | void | 设置流的状态,通常用于错误恢复。 |
void resetStatus() | void | 重置流状态为Ok。 |
测试代码 - 设备与状态管理
#include <QTextStream>
#include <QFile>
#include <QDebug>
int main() {
QFile file("test.txt");
file.open(QIODevice::ReadWrite);
QTextStream stream(&file);
qDebug() << "设备:" << (stream.device() == &file);
qDebug() << "初始状态:" << stream.status();
// 设置新设备
QFile file2("test2.txt");
file2.open(QIODevice::WriteOnly);
stream.setDevice(&file2);
qDebug() << "新设备:" << (stream.device() == &file2);
// 设置状态
stream.setStatus(QTextStream::WriteFailed);
qDebug() << "设置错误状态:" << stream.status();
// 重置状态
stream.resetStatus();
qDebug() << "重置后状态:" << stream.status();
return 0;
}
// ======================
// console
// ======================
//设备: true
//初始状态: 0
//新设备: true
//设置错误状态: 3
//重置后状态: 0
读取操作
方法 | 返回类型 | 描述 |
---|---|---|
bool atEnd() const | bool | 返回true如果流已到达末尾。 |
QString read(qint64 maxlen) | QString | 读取最多maxlen个字符,若为 0 则读取全部。 |
QString readAll() const | QString | 读取流中所有剩余内容。 |
QString readLine(qint64 maxlen = 0) | QString | 读取一行,最多maxlen个字符(0 表示无限制)。 |
bool readLineInto(QString *line, qint64 maxlen = 0) | bool | 读取一行到指定QString,返回true如果成功。 |
void skipWhiteSpace() | void | 跳过流中的空白字符。 |
测试代码 - 读取操作
#include <QTextStream>
#include <QFile>
#include <QDebug>
int main() {
QFile file("test.txt");
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
out << "Hello\nWorld\n Test";
file.close();
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
qDebug() << "读取一行:" << in.readLine();
qDebug() << "是否末尾:" << in.atEnd();
qDebug() << "读取全部:" << in.readAll();
// 重置并测试其他方法
file.seek(0);
QString line;
in.readLineInto(&line);
qDebug() << "readLineInto:" << line;
file.seek(0);
in.skipWhiteSpace();
qDebug() << "跳过空白后读取:" << in.read(5);
file.close();
return 0;
}
// ======================
// console
// ======================
//读取一行: "Hello"
//是否末尾: false
//读取全部: "World\n Test"
//readLineInto: "Hello"
//跳过空白后读取: "World"
写入操作
方法 | 返回类型 | 描述 |
---|---|---|
void flush() | void | 刷新缓冲区,将数据写入底层设备。 |
QTextStream &operator<<(类型) | QTextStream & | 重载操作符,支持写入多种类型(如QString 、int、double等)。 |
测试代码 - 写入操作
#include <QTextStream>
#include <QFile>
#include <QDebug>
int main() {
QFile file("output.txt");
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
out << "Hello " << 123 << " World\n" << 3.14;
out.flush();
qDebug() << "写入完成,检查文件 output.txt";
file.close();
return 0;
}
// ======================
// console
// ======================
//写入完成,检查文件 output.txt
位置与导航
方法 | 返回类型 | 描述 |
---|---|---|
qint64 pos() const | qint64 | 返回流中当前位置。 |
bool seek(qint64 pos) | bool | 将流定位到指定位置,返回true如果成功。 |
void reset() | void | 重置流的状态和格式设置,但不影响位置。 |
测试代码 - 位置与导航
#include <QTextStream>
#include <QFile>
#include <QDebug>
int main() {
QFile file("test.txt");
file.open(QIODevice::ReadWrite);
QTextStream stream(&file);
stream << "Hello World";
qDebug() << "当前位置:" << stream.pos();
stream.seek(6);
qDebug() << "定位后读取:" << stream.readLine();
stream.reset();
qDebug() << "重置后状态:" << stream.status();
file.close();
return 0;
}
// ======================
// console
// ======================
//当前位置: 0
//定位后读取: "World"
//重置后状态: 0
编码与格式设置
方法 | 返回类型 | 描述 |
---|---|---|
QTextCodec *codec() const | QTextCodec * | 返回当前使用的文本编码。 |
void setCodec(QTextCodec *codec) | void | 设置文本编码。 |
void setCodec(const char *codecName) | void | 通过编码名称设置编码(如 "UTF-8")。 |
QString codec().name() const | QString | 返回当前编码名称。 |
void setAutoDetectUnicode(bool enabled) | void | 设置是否自动检测 Unicode(默认启用)。 |
bool autoDetectUnicode() const | bool | 返回是否启用 Unicode 自动检测。 |
void setGenerateByteOrderMark(bool generate) | void | 设置是否生成字节顺序标记(BOM,默认禁用)。 |
bool generateByteOrderMark() const | bool | 返回是否生成 BOM。 |
测试代码 - 编码与格式设置
#include <QTextStream>
#include <QFile>
#include <QTextCodec>
#include <QDebug>
int main() {
QFile file("test.txt");//created ./test.txt
file.open(QIODevice::WriteOnly);
QTextStream stream(&file);
qDebug() << "默认编码:" << stream.codec()->name();
stream.setCodec("UTF-16");
qDebug() << "设置后编码:" << stream.codec()->name();
stream.setGenerateByteOrderMark(true);
qDebug() << "生成 BOM:" << stream.generateByteOrderMark();
stream.setAutoDetectUnicode(false);
qDebug() << "自动检测 Unicode:" << stream.autoDetectUnicode();
stream << "测试编码";
file.close();
return 0;
}
// ======================
// console
// ======================
//默认编码: "UTF-8"
//设置后编码: "UTF-16"
//生成 BOM: true
//自动检测 Unicode: false
格式化选项
方法 | 返回类型 | 描述 |
---|---|---|
int fieldWidth() const | int | 返回字段宽度(默认 0 表示无限制)。 |
void setFieldWidth(int width) | void | 设置字段宽度,用于对齐。 |
FieldAlignment fieldAlignment() const | FieldAlignment | 返回字段对齐方式。 |
void setFieldAlignment(FieldAlignment alignment) | void | 设置字段对齐方式。 |
QChar padChar() const | QChar | 返回填充字符(默认空格)。 |
void setPadChar(QChar ch) | void | 设置填充字符。 |
NumberFlags numberFlags() const | NumberFlags | 返回数字格式标志。 |
void setNumberFlags(NumberFlags flags) | void | 设置数字格式标志。 |
int integerBase() const | int | 返回整数基数(默认 10,范围 2-36)。 |
void setIntegerBase(int base) | void | 设置整数基数。 |
RealNumberNotation realNumberNotation() const | RealNumberNotation | 返回实数表示法。 |
void setRealNumberNotation(RealNumberNotation notation) | void | 设置实数表示法。 |
int realNumberPrecision() const | int | 返回实数精度(默认 6)。 |
void setRealNumberPrecision(int precision) | void | 设置实数精度。 |
测试代码 - 格式化选项
#include <QTextStream>
#include <QFile>
#include <QDebug>
int main() {
QFile file("format.txt");
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
out.setFieldWidth(10);
out.setFieldAlignment(QTextStream::AlignRight);
out.setPadChar('-');
out << "Test" << 123;
qDebug() << "字段宽度:" << out.fieldWidth();
out.setNumberFlags(QTextStream::ShowBase | QTextStream::UppercaseBase);
out.setIntegerBase(16);
out << "\n" << 255;
qDebug() << "数字标志:" << out.numberFlags();
out.setRealNumberNotation(QTextStream::ScientificNotation);
out.setRealNumberPrecision(2);
out << "\n" << 3.14159;
qDebug() << "实数精度:" << out.realNumberPrecision();
file.close();
return 0;
}
// ======================
// console
// ======================
//字段宽度: 10
//数字标志: QFlags(0x1|0x8)
//实数精度: 2
//=========format.txt=========
//------Test-------123---------
//------0Xff---------
//--3.14e+00
字符串操作
方法 | 返回类型 | 描述 |
---|---|---|
QString *string() const | QString * | 返回绑定的QString指针,若未绑定返回nullptr。 |
void setString(QString *string, QIODevice::OpenMode openMode = QIODevice::ReadWrite) | void | 设置绑定的QString,替换现有绑定。 |
测试代码 - 字符串操作
#include <QTextStream>
#include <QString>
#include <QDebug>
int main() {
QString str;
QTextStream stream(&str);
qDebug() << "初始字符串:" << (stream.string() == &str);
stream << "Hello World";
qDebug() << "写入后:" << str;
QString str2;
stream.setString(&str2);
stream << "New Text";
qDebug() << "新字符串:" << str2;
return 0;
}
// ======================
// console
// ======================
//初始字符串: true
//写入后: "Hello World"
//新字符串: "New Text"
输入操作符
方法 | 返回类型 | 描述 |
---|---|---|
QTextStream &operator>>(类型) | QTextStream & | 重载操作符,支持读取多种类型(如QString 、int、double等)。 |
测试代码 - 输入操作符
#include <QTextStream>
#include <QFile>
#include <QDebug>
int main() {
QFile file("input.txt");
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
out << "Hello 123 3.14";
file.close();
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
QString str;
int num;
double real;
in >> str >> num >> real;
qDebug() << "读取结果:" << str << num << real;
file.close();
return 0;
}
// ======================
// console
// ======================
//读取结果: "Hello" 123 3.14
注意事项
-
编码:默认使用 UTF-8,若设备支持 BOM 则优先检测。
-
换行符:跨平台统一处理(读取时转换为 \n,写入时使用本地换行符)。
-
状态:读取或写入失败后需检查 status() 或重置。
-
设备管理:QTextStream 不负责关闭设备,需手动管理。
5、QDataStream
QDataStream
用于二进制数据的序列化和反序列化,常用于高效地存储和传输数据。
6、QBuffer
QBuffer 是 Qt Core 模块中的类,继承自 QIODevice,提供了一个内存缓冲区,用于在内存中读写数据。它基于 QByteArray,适合临时存储或处理字节数据。QBuffer 是隐式共享类,所有方法可重入(reentrant),线程安全。主要功能包括:
-
在内存中读写字节数据。
-
提供流式操作接口。
-
支持定位和缓冲区管理。
构造函数
构造函数 | 描述 |
---|---|
QBuffer(QObject *parent = nullptr) | 构造一个空的QBuffer对象,可指定父对象。 |
QBuffer(QByteArray *byteArray, QObject *parent = nullptr) | 构造一个绑定到指定QByteArray的QBuffer 对象。 |
测试代码 - 构造函数
#include <QBuffer>
#include <QByteArray>
#include <QDebug>
int main() {
// 空构造函数
QBuffer buffer1;
qDebug() << "空构造函数:" << (buffer1.buffer().isEmpty() ? "空" : "非空");
// QByteArray 构造函数
QByteArray data("Initial Data");
QBuffer buffer2(&data);
qDebug() << "QByteArray 构造函数:" << buffer2.buffer();
return 0;
}
// ======================
// console
// ======================
//空构造函数: 空
//QByteArray 构造函数: "Initial Data"
析构函数
析构函数 | 描述 |
---|---|
~QBuffer() | 销毁对象,不释放绑定的QByteArray数据。 |
缓冲区管理
方法 | 返回类型 | 描述 |
---|---|---|
const QByteArray &buffer() const | const QByteArray & | 返回当前绑定的缓冲区数据(只读引用)。 |
QByteArray &buffer() | QByteArray & | 返回当前绑定的缓冲区数据(可写引用)。 |
void setBuffer(QByteArray *byteArray) | void | 设置新的QByteArray作为缓冲区,替换现有缓冲区。 |
bool setData(const QByteArray &data) | bool | 用指定数据初始化内部缓冲区,返回true如果成功。 |
bool setData(const char *data, qsizetype size) | bool | 用指定字符数组和大小初始化内部缓冲区,返回true如果成功。 |
QByteArray data() const | QByteArray | 返回缓冲区中的数据副本。 |
测试代码 - 缓冲区管理
#include <QBuffer>
#include <QByteArray>
#include <QDebug>
int main() {
QBuffer buffer;
qDebug() << "初始缓冲区:" << buffer.buffer();
// 设置缓冲区
QByteArray newData("New Data");
buffer.setBuffer(&newData);
qDebug() << "设置缓冲区后:" << buffer.buffer();
// 设置数据
buffer.setData("Test Data", 9);
qDebug() << "设置数据后:" << buffer.data();
// 获取可写缓冲区并修改
buffer.buffer().append(" Appended");
qDebug() << "修改缓冲区后:" << buffer.buffer();
return 0;
}
// ======================
// console
// ======================
//初始缓冲区: ""
//设置缓冲区后: "New Data"
//设置数据后: "Test Data"
//修改缓冲区后: "Test Data Appended"
设备状态与操作
方法 | 返回类型 | 描述 |
---|---|---|
bool open(OpenMode mode) | bool | 以指定模式打开缓冲区(ReadOnly、WriteOnly 、ReadWrite),返回true如果成功。 |
void close() | void | 关闭缓冲区,但不影响缓冲区数据。 |
bool isOpen() const | bool | 返回true如果缓冲区已打开。 |
OpenMode openMode() const | QIODevice::OpenMode | 返回当前打开模式。 |
测试代码 - 设备状态与操作
#include <QBuffer>
#include <QDebug>
int main() {
QBuffer buffer;
qDebug() << "初始打开状态:" << buffer.isOpen();
// 打开缓冲区
buffer.open(QIODevice::ReadWrite);
qDebug() << "打开后状态:" << buffer.isOpen();
qDebug() << "打开模式:" << buffer.openMode();
// 关闭缓冲区
buffer.close();
qDebug() << "关闭后状态:" << buffer.isOpen();
return 0;
}
// ======================
// console
// ======================
//初始打开状态: false
//打开后状态: true
//打开模式: OpenMode( "ReadOnly|Unbuffered|WriteOnly" )
//关闭后状态: false
读取与写入
QBuffer 直接相关接口
QBuffer 本身没有定义新的读写操作符(如 << 或 >>),但提供了一些与读写密切相关的方法,主要用于管理缓冲区和数据。
接口名称 | 描述 | 用法示例 |
---|---|---|
void write(const char *data, qint64 len) | 写入指定长度的数据到缓冲区 | buffer.write("Qt", 2); |
qint64 read(char *data, qint64 maxSize) | 从缓冲区读取指定最大长度的数据 | char buf[10]; buffer.read(buf, 10); |
QByteArray& buffer() | 返回内部缓冲区的引用,可直接修改 | buffer.buffer().append("data"); |
const QByteArray data() const | 返回缓冲区中的数据副本 | QByteArray d = buffer.data(); |
void setBuffer(QByteArray *byteArray) | 设置使用的缓冲区(需在未打开时调用) | QByteArray ba; buffer.setBuffer(&ba); |
void setData(const QByteArray &data) | 设置缓冲区内容(需在未打开时调用) | buffer.setData(QByteArray("test")); |
测试代码 - QBuffer 直接相关接口
#include <QCoreApplication>
#include <QBuffer>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// 创建 QBuffer 对象
QBuffer buffer;
qDebug() << "=== 测试 QBuffer 直接相关接口 ===";
// 测试 setData(const QByteArray &data)
QByteArray initialData = "Initial Data";
buffer.setData(initialData);
qDebug() << "setData 后缓冲区内容: " << buffer.data();
// 测试 setBuffer(QByteArray *byteArray)
QByteArray externalBuffer;
buffer.setBuffer(&externalBuffer);
qDebug() << "setBuffer 后外部缓冲区内容: " << externalBuffer; // 空
// 测试 write(const char *data, qint64 len)
if (buffer.open(QIODevice::WriteOnly)) {
buffer.write("Hello, Qt!", 10);
qDebug() << "write 后缓冲区内容: " << buffer.data();
qDebug() << "write 后外部缓冲区内容: " << externalBuffer; // 同步更新
buffer.close();
}
// 测试 read(char *data, qint64 maxSize)
if (buffer.open(QIODevice::ReadOnly)) {
char readBuffer[20];
qint64 bytesRead = buffer.read(readBuffer, 5);
readBuffer[bytesRead] = '\0'; // 添加字符串终止符
qDebug() << "read 读取 " << bytesRead << " 字节: " << readBuffer;
buffer.close();
}
// 测试 buffer()
buffer.buffer().append(" Appended");
qDebug() << "buffer() 修改后内容: " << buffer.data();
// 测试 data() const
QByteArray dataCopy = buffer.data();
qDebug() << "data() 返回副本: " << dataCopy;
return app.exec();
}
// ======================
// console
// ======================
//=== 测试 QBuffer 直接相关接口 ===
//setData 后缓冲区内容: "Initial Data"
//setBuffer 后外部缓冲区内容: ""
//write 后缓冲区内容: "Hello, Qt!"
//write 后外部缓冲区内容: "Hello, Qt!"
//read 读取 5 字节: Hello
//buffer() 修改后内容: "Hello, Qt! Appended"
//data() 返回副本: "Hello, Qt! Appended"
继承自 QIODevice 的读取接口
这些接口由 QBuffer 从 QIODevice 继承而来,适用于随机访问设备(如 QBuffer)。
接口名称 | 描述 | 用法示例 |
---|---|---|
qint64 read(char *data, qint64 maxSize) | 读取最多 maxSize 字节到指定缓冲区 | char buf[10]; buffer.read(buf, 10); |
QByteArray read(qint64 maxSize) | 读取最多 maxSize 字节并返回 QByteArray | QByteArray data = buffer.read(5); |
QByteArray readAll() | 读取缓冲区中所有剩余数据 | QByteArray all = buffer.readAll(); |
qint64 readLine(char *data, qint64 maxSize) | 读取一行到缓冲区,最多 maxSize 字节 | char line[100]; buffer.readLine(line, 100); |
QByteArray readLine(qint64 maxSize = 0) | 读取一行并返回 QByteArray | QByteArray line = buffer.readLine(); |
qint64 peek(char *data, qint64 maxSize) | 预览最多 maxSize 字节,不移动位置 | char peek[10]; buffer.peek(peek, 10); |
QByteArray peek(qint64 maxSize) | 预览数据并返回 QByteArray,不移动位置 | QByteArray p = buffer.peek(5); |
int getChar(char *c) | 读取单个字符到指定指针 | char ch; buffer.getChar(&ch); |
bool canReadLine() const | 检查是否可以读取完整一行 | if (buffer.canReadLine()) { ... } |
测试代码 - 继承自 QIODevice 的读取接口
#include <QCoreApplication>
#include <QBuffer>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// 创建 QBuffer 对象并设置初始数据
QBuffer buffer;
QByteArray initialData = "Line1\nLine2\nLine3";
buffer.setData(initialData);
qDebug() << "=== 测试继承自 QIODevice 的读取接口 ===";
if (buffer.open(QIODevice::ReadOnly)) {
// 测试 read(char *data, qint64 maxSize)
char readBuffer[10];
qint64 bytesRead = buffer.read(readBuffer, 5);
readBuffer[bytesRead] = '\0';
qDebug() << "read(char*, maxSize) 读取: " << readBuffer;
// 测试 read(qint64 maxSize)
QByteArray chunk = buffer.read(3);
qDebug() << "read(maxSize) 读取: " << chunk;
// 测试 readLine(char *data, qint64 maxSize)
char lineBuffer[20];
buffer.readLine(lineBuffer, 20);
qDebug() << "readLine(char*, maxSize) 读取: " << lineBuffer;
// 测试 readLine(qint64 maxSize = 0)
QByteArray line = buffer.readLine();
qDebug() << "readLine() 读取: " << line;
// 测试 readAll()
QByteArray remaining = buffer.readAll();
qDebug() << "readAll() 读取: " << remaining;
// 重置位置以测试 peek
buffer.seek(0);
// 测试 peek(char *data, qint64 maxSize)
char peekBuffer[10];
buffer.peek(peekBuffer, 5);
peekBuffer[5] = '\0';
qDebug() << "peek(char*, maxSize) 预览: " << peekBuffer;
qDebug() << "peek 后位置: " << buffer.pos();
// 测试 peek(qint64 maxSize)
QByteArray peeked = buffer.peek(5);
qDebug() << "peek(maxSize) 预览: " << peeked;
// 测试 getChar(char *c)
char ch;
buffer.getChar(&ch);
qDebug() << "getChar 读取字符: " << ch;
// 测试 canReadLine()
qDebug() << "canReadLine(): " << buffer.canReadLine();
buffer.close();
} else {
qDebug() << "无法打开缓冲区";
}
return app.exec();
}
// ======================
// console
// ======================
//=== 测试继承自 QIODevice 的读取接口 ===
//read(char*, maxSize) 读取: Line1
//read(maxSize) 读取: "\nLi"
//readLine(char*, maxSize) 读取: ne2
//readLine() 读取: "Line3"
//readAll() 读取: ""
//peek(char*, maxSize) 预览: Line1
//peek 后位置: 0
//peek(maxSize) 预览: "Line1"
//getChar 读取字符: L
//canReadLine(): true
继承自 QIODevice 的写入接口
这些接口同样由 QBuffer 从 QIODevice 继承而来,用于写入数据。
接口名称 | 描述 | 用法示例 |
---|---|---|
qint64 write(const char *data, qint64 len) | 写入指定长度的数据 | buffer.write("Qt", 2); |
qint64 write(const char *data) | 写入以空字符结尾的字符串 | buffer.write("Qt"); |
qint64 write(const QByteArray &byteArray) | 写入 QByteArray 的内容 | buffer.write(QByteArray("Qt")); |
int putChar(char c) | 写入单个字符 | buffer.putChar('Q'); |
测试代码 - 继承自 QIODevice 的写入接口
#include <QCoreApplication>
#include <QBuffer>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// 创建 QBuffer 对象
QBuffer buffer;
qDebug() << "=== 测试继承自 QIODevice 的写入接口 ===";
if (buffer.open(QIODevice::WriteOnly)) {
// 测试 write(const char *data, qint64 len)
buffer.write("Hello", 5);
qDebug() << "write(const char*, len) 后: " << buffer.data();
// 测试 write(const char *data)
buffer.write(" Qt");
qDebug() << "write(const char*) 后: " << buffer.data();
// 测试 write(const QByteArray &byteArray)
QByteArray moreData = " Framework";
buffer.write(moreData);
qDebug() << "write(QByteArray) 后: " << buffer.data();
// 测试 putChar(char c)
buffer.putChar('!');
qDebug() << "putChar 后: " << buffer.data();
buffer.close();
} else {
qDebug() << "无法打开缓冲区";
}
return app.exec();
}
// ======================
// console
// ======================
//=== 测试继承自 QIODevice 的写入接口 ===
//write(const char*, len) 后: "Hello"
//write(const char*) 后: "Hello Qt"
//write(QByteArray) 后: "Hello Qt Framework"
//putChar 后: "Hello Qt Framework!"
位置与导航
方法 | 返回类型 | 描述 |
---|---|---|
bool atEnd() const | bool | 返回true如果已到达缓冲区末尾。 |
qint64 pos() const | qint64 | 返回当前位置。 |
bool seek(qint64 pos) | bool | 将位置移动到pos,返回true如果成功。 |
qint64 size() const | qint64 | 返回缓冲区总大小。 |
测试代码 - 位置与导航
#include <QBuffer>
#include <QDebug>
int main() {
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
buffer.write("Hello World");
qDebug() << "缓冲区大小:" << buffer.size();
qDebug() << "当前位置:" << buffer.pos();
buffer.seek(6);
qDebug() << "定位后位置:" << buffer.pos();
qDebug() << "是否末尾:" << buffer.atEnd();
buffer.seek(buffer.size());
qDebug() << "移动到末尾后:" << buffer.atEnd();
buffer.close();
return 0;
}
// ======================
// console
// ======================
//缓冲区大小: 11
//当前位置: 11
//定位后位置: 6
//是否末尾: false
//移动到末尾后: true
其他(继承自 QIODevice 的方法)
方法 | 返回类型 | 描述 |
---|---|---|
bool canReadLine() const | bool | 返回true如果可以读取一行(缓冲区包含换行符或未到末尾)。 |
bool isSequential() const | bool | 返回false,表示QBuffer是随机访问设备。 |
测试代码 - 其他
#include <QBuffer>
#include <QDebug>
int main() {
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
buffer.write("Line1\nLine2");
qDebug() << "是否顺序设备:" << buffer.isSequential();
qDebug() << "可读取行:" << buffer.canReadLine();
buffer.seek(buffer.size());
qDebug() << "末尾时可读取行:" << buffer.canReadLine();
buffer.close();
return 0;
}
// ======================
// console
// ======================
//是否顺序设备: false
//可读取行: false
//末尾时可读取行: false
注意事项
-
缓冲区所有权:QBuffer 不负责管理绑定的 QByteArray 的生命周期,需外部维护。
-
打开模式:使用前必须调用 open(),否则读写操作无效。
-
性能:适合小规模内存操作,大数据建议使用文件或其他设备。
-
线程安全:方法可重入,但多个线程访问同一 QBuffer 需同步。
7、QFile/QDir/QTextStream/QBuffe区别及应用场景
区别对比
类名 | 定义与功能 | 主要特点 | 数据存储位置 | 继承关系 |
---|---|---|---|---|
QFile | 用于直接操作文件系统中的文件,提供对文件的读写功能。 | 底层文件操作,支持二进制和文本数据,适用于物理文件读写。 | 磁盘上的物理文件 | 继承自 QIODevice |
QDir | 用于操作文件系统中的目录,提供目录导航、文件列表和路径管理的功能。 | 不直接读写文件内容,而是管理目录结构和文件元信息(如路径、文件名、过滤等)。 | 文件系统中的目录 | 无直接继承 QIODevice |
QTextStream | 提供对文本流的读写接口,支持多种设备(如文件、缓冲区),处理编码和格式化输出。 | 高层文本处理,自动管理编码和换行符,支持格式化输入输出,适用于文本数据操作。 | 依赖底层设备(如文件或缓冲区) | 无直接继承,但常与 QIODevice 配合 |
QBuffer | 用于在内存中操作字节数组( QByteArray ),提供内存缓冲区的读写功能。 | 内存操作,无需物理文件,适用于临时数据存储或序列化,速度快。 | 内存中的 QByteArray | 继承自 QIODevice |
功能定位:
-
QFile: 专注于物理文件的读写,是底层的 I/O 操作工具。
-
QDir: 专注于目录管理,不涉及文件内容操作。
-
QTextStream: 专注于文本数据的流式处理,提供高级接口,依赖底层设备。
-
QBuffer: 专注于内存中的数据操作,适合临时或快速处理。
数据类型:
-
QFile 和 QBuffer: 处理二进制数据(QByteArray)或文本数据(通过 QTextStream)。
-
QDir: 不处理数据内容,仅操作路径和文件元信息。
-
QTextStream: 专为文本数据设计,支持多种编码和格式化。
依赖性:
-
QFile 和 QBuffer 是独立的 QIODevice 子类,可直接使用。
-
QTextStream 需要绑定到一个 QIODevice(如 QFile 或 QBuffer)或字符串。
-
QDir 不依赖其他 I/O 类,独立操作文件系统。
性能与存储:
-
QFile: 涉及磁盘 I/O,速度较慢但持久化。
-
QBuffer: 内存操作,速度快但数据易失。
-
QTextStream: 性能依赖底层设备。
-
QDir: 不涉及数据读写,性能与文件系统操作相关。
应用场景
QFile 直接读写磁盘上的文件,支持二进制和文本操作。
-
日志记录: 将日志写入磁盘文件。
-
配置文件读写: 读取或保存应用程序设置。
-
大文件处理: 处理二进制文件(如图像、音频)。
-
优点: 数据持久化,适合需要长期存储的场景。
-
缺点: 磁盘 I/O 较慢。
QDir管理目录结构,列出文件,创建/删除目录等。
-
文件浏览器: 获取目录中的文件列表。
-
目录清理: 删除过期文件或创建新目录。
-
路径管理: 检查路径是否存在或规范化路径。
-
优点: 专注于目录操作,简单高效。
-
缺点: 不涉及文件内容处理。
QTextStream 提供文本流的读写接口,支持格式化和编码处理。
-
文本文件读写: 从文件中读取配置或写入报告。
-
标准输入输出: 从控制台读取用户输入。
-
格式化输出: 生成结构化的文本数据。
-
优点: 跨平台文本处理,编码支持强大。
-
缺点: 不适合二进制数据,依赖底层设备。
QBuffer 在内存中操作字节数组,适合临时数据处理。
-
数据序列化: 临时存储序列化数据。
-
内存缓存: 在处理前缓存数据。
-
测试与调试: 模拟文件操作而不触及磁盘。
-
优点: 速度快,无磁盘 I/O 开销。
-
缺点: 数据不持久,内存占用受限。
类 | 使用场景 | 何时选择 |
---|---|---|
QFile | 需要读写物理文件 | 数据需持久化存储到磁盘 |
QDir | 需要管理目录或文件列表 | 处理文件系统结构而非内容 |
QTextStream | 需要处理文本数据(格式化、编码) | 跨平台文本读写或用户交互 |
QBuffer | 需要内存中临时处理数据 | 快速操作或避免磁盘 I/O |
组合使用
以下是一个结合 QFile、QDir、QTextStream 和 QBuffer 的示例,展示它们如何协同工作:
-
QFile + QTextStream: 读写文本文件。
-
QBuffer + QTextStream: 内存中处理文本。
-
QDir + QFile: 管理目录并操作文件。
-
QBuffer + QFile: 内存缓存后写入文件。
测试代码-组合使用
#include <QCoreApplication>
#include <QFile>
#include <QDir>
#include <QTextStream>
#include <QBuffer>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
// 使用 QDir 创建目录
QDir dir;
dir.mkdir("test_dir");
// 使用 QFile 和 QTextStream 写入文件
QFile file("test_dir/data.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&file);
out << "Hello from QFile\n";
file.close();
}
// 使用 QBuffer 处理内存数据
QBuffer buffer;
buffer.open(QIODevice::WriteOnly);
QTextStream bufferOut(&buffer);
bufferOut << "Data in memory\n";
buffer.close();
// 将 QBuffer 数据写入文件
if (file.open(QIODevice::Append)) {
file.write(buffer.data());
file.close();
}
// 使用 QDir 检查文件并用 QTextStream 读取
if (dir.exists("test_dir/data.txt")) {
QFile readFile("test_dir/data.txt");
if (readFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&readFile);
qDebug() << "文件内容:\n" << in.readAll();
readFile.close();
}
}
return app.exec();
}
// ======================
// console
// ======================
//文件内容:
// "Hello from QFile\nData in memory\n"
三. 事件系统 (Event System)
-
QEvent
QEvent
是 Qt 的事件类,用于表示用户交互、系统事件等。 -
QObject
QObject
是 Qt 所有对象的基类。它支持信号和槽机制、事件处理等功能。 -
QTimer
QTimer
类用于定时任务,它提供定时器功能,允许在指定时间间隔后触发某个操作。 -
QCoreApplication
QCoreApplication
是应用程序核心类,负责启动事件循环和管理应用程序的生命周期。 -
QEventLoop
事件循环管理类。
-
QMetaObject:
支持元对象系统,提供动态方法调用和属性访问。
四. 多线程和并发 (Multithreading and Concurrency)
-
QThread
QThread
提供了线程管理的功能,允许开发者创建和管理线程。 -
同步工具QMutex、QReadWriteLock、QSemaphore、QWaitCondition
QMutex:互斥锁,确保线程安全。
QReadWriteLock:读写锁,适用于多读少写场景。
QSemaphore:信号量,控制资源访问。
QWaitCondition:线程等待条件。
-
QThreadPool 和 QRunnable
线程池管理。
-
原子操作
QAtomicInt 和 QAtomicPointer 提供线程安全的原子操作。
-
QtConcurrent
QtConcurrent
提供了对并行计算的高层次抽象。它允许开发者简洁地进行多线程任务处理,如并行遍历、过滤等操作。
五. 国际化和本地化 (Internationalization and Localization)
-
QLocale
QLocale
类用于管理语言、区域设置等本地化信息,能够根据不同的区域设置显示日期、时间、数字等格式。 -
QTranslator
QTranslator
用于加载翻译文件,以便将应用程序界面翻译成不同的语言。
六. 进程和进程间通信 (Process and Inter-Process Communication - IPC)
-
QProcess
QProcess
类用于启动外部进程并与其进行交互,支持进程输入输出流的管理。 -
QLocalSocket, QLocalServer
-
QLocalSocket
: 本地套接字,用于与本地进程进行通信。 -
QLocalServer
: 本地服务器,用于监听来自其他进程的连接请求。
-
-
QSharedMemory
QSharedMemory
提供了进程间共享内存的访问,允许多个进程共享同一块内存区域。
七. 插件支持 (Plugin Support)
-
QPluginLoader
QPluginLoader
用于加载动态插件,使得应用程序能够在运行时加载和卸载插件。 -
QFactoryInterface
QFactoryInterface
是插件接口,插件可以实现特定功能,并通过该接口供应用程序使用。
八. 文本编解码 (Text Codecs)
-
QTextCodec
QTextCodec
用于文本编码和解码,支持多种字符集,如 UTF-8、GBK、ISO-8859-1 等。
九. 动态库加载 (Dynamic Library Loading)
-
QLibrary
QLibrary
用于加载动态链接库,并提供访问其导出函数的能力,支持跨平台的动态库管理。
十. 全局函数
-
qAbs
计算绝对值。
-
qDebug、qWarning、qCritical
调试和日志输出。
-
qInstallMsgHandler
安装消息处理程序。
-
qVersion
返回 Qt 版本。
-
qRegisterResourceData 和 qUnregisterResourceData:
资源数据管理。
十一. 其他实用工具
-
QUrl
URL 解析和生成。
-
QRandomGenerator
线程安全的随机数生成。
-
QCryptographicHas
加密哈希类(如 MD5、SHA-256)。
-
QJsonDocument、QJsonArray、QJsonObject、QJsonValue
JSON 处理:
-
QRegularExpression
Perl 兼容的正则表达式。
-
QSettings
跨平台应用设置存储。
-
QStandardPaths
返回标准目录路径。
-
QDebug
调试输出工具。
-
QCalendar
支持多种日历系统。
-
QDeadlineTimer
截止时间管理。