文件操作
1. 文件读写
QFile - 基本文件操作
// 只写模式创建文件(如果文件已存在会清空内容)
file.open(QIODevice::WriteOnly);
// 读写模式创建文件
file.open(QIODevice::ReadWrite);
// 追加模式(如果文件不存在则创建)
file.open(QIODevice::Append);
// 文本模式(处理换行符转换)
file.open(QIODevice::WriteOnly | QIODevice::Text);
// 读取文件
QFile file("test.txt");
if(file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream in(&file);
QString content = in.readAll();
file.close();
}
// 写入文件
QFile outFile("output.txt");
if(outFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&outFile);
out << "Hello QT!" << Qt::endl;
outFile.close();
}
检查并创建文件(避免覆盖)
void createFileIfNotExists() {
QString filename = "newfile.txt";
if (QFile::exists(filename)) {
qDebug() << "文件已存在";
return;
}
QFile file(filename);
if (file.open(QIODevice::WriteOnly)) {
qDebug() << "文件创建成功";
file.close();
}
}
QTextStream - 文本流操作
QFile file("data.txt");
if(file.open(QIODevice::ReadWrite | QIODevice::Text)) {
QTextStream stream(&file);
stream.setCodec("UTF-8"); // 设置编码
QString line;
while(!stream.atEnd()) {
line = stream.readLine(); // 逐行读取
}
}
QDataStream - 二进制数据操作
QFile file("data.bin");
if(file.open(QIODevice::WriteOnly)) {
QDataStream out(&file);
out << QString("QT") << qint32(123) << 3.14159;
file.close();
}
void createBinaryFile() {
QFile file("data.bin");
if (file.open(QIODevice::WriteOnly)) {
QDataStream out(&file);
out << quint32(0x12345678); // 写入32位无符号整数
out << 3.1415926; // 写入双精度浮点数
file.close();
}
}
2. 文件信息
QFileInfo - 获取文件信息
QFileInfo info("example.txt");
qDebug() << "文件大小:" << info.size();
qDebug() << "创建时间:" << info.created();
qDebug() << "最后修改时间:" << info.lastModified();
qDebug() << "文件路径:" << info.absoluteFilePath();
qDebug() << "后缀名:" << info.suffix();
qDebug() << "是否存在:" << info.exists();
3. 文件操作
// 复制文件
QFile::copy("source.txt", "dest.txt");
// 重命名文件
QFile::rename("old.txt", "new.txt");
// 删除文件
QFile::remove("fileToDelete.txt");
// 文件是否存在
bool exists = QFile::exists("test.txt");
文件夹操作
1. 目录操作
QDir - 基本目录操作
// 创建目录
QDir().mkdir("newDir");
// 创建多级目录
QDir().mkpath("path/to/new/dir");
// 删除目录
QDir().rmdir("emptyDir"); // 只能删除空目录
QDir().rmpath("path/to/dir"); // 可以删除多级空目录
// 重命名目录
QDir().rename("oldDir", "newDir");
// 检查目录是否存在
bool dirExists = QDir("myDir").exists();
2. 遍历目录
QDir dir("/path/to/directory");
// 获取所有文件和目录
QStringList entries = dir.entryList(QDir::NoDotAndDotDot | QDir::AllEntries);
// 获取所有文件(不包括目录)
QStringList files = dir.entryList(QDir::Files);
// 获取特定类型的文件
QStringList images = dir.entryList(QStringList() << "*.jpg" << "*.png", QDir::Files);
// 递归遍历目录
void traverseDir(const QString &path) {
QDir dir(path);
foreach(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files)) {
if(info.isDir()) {
traverseDir(info.absoluteFilePath());
} else {
qDebug() << "File:" << info.absoluteFilePath();
}
}
}
3. 路径操作
QString path = "/home/user/docs/report.txt";
// 获取文件名
QString fileName = QFileInfo(path).fileName(); // "report.txt"
// 获取基本名(无后缀)
QString baseName = QFileInfo(path).baseName(); // "report"
// 获取目录路径
QString dirPath = QFileInfo(path).absolutePath(); // "/home/user/docs"
// 组合路径
QString newPath = QDir("/home/user").filePath("downloads"); // "/home/user/downloads"
// 清理路径中的冗余部分
QString cleanPath = QDir::cleanPath("/home//user/../user/docs"); // "/home/user/docs"
//将路径中的分隔符转换为当前系统的本地分隔符
QString path = "C:/Qt/examples/widgets";
QString nativePath = QDir::toNativeSeparators(path);
// 在Windows上返回 "C:\Qt\examples\widgets"
// 在Linux/macOS上保持不变 "C:/Qt/examples/widgets"
//将本地分隔符转换为通用的正斜杠 /
QString nativePath = "C:\\Qt\\examples\\widgets";
QString genericPath = QDir::fromNativeSeparators(nativePath);
// 返回 "C:/Qt/examples/widgets" (所有平台)
//直接使用正斜杠 /
//Qt 内部会自动处理路径分隔符,因此最简单的方法是始终使用正斜杠:
QString path = "C:/Qt/examples/widgets"; // 在所有平台上都有效
QFile file(path); // Qt会自动处理分隔符转换
高级操作
1. 文件监视
QFileSystemWatcher watcher;
watcher.addPath("/path/to/file.txt");
watcher.addPath("/path/to/directory");
QObject::connect(&watcher, &QFileSystemWatcher::fileChanged,
[](const QString &path) { qDebug() << "File changed:" << path; });
QObject::connect(&watcher, &QFileSystemWatcher::directoryChanged,
[](const QString &path) { qDebug() << "Directory changed:" << path; });
2. 临时文件
// 自动删除的临时文件
QTemporaryFile tempFile;
if(tempFile.open()) {
tempFile.write("Temporary data");
tempFile.close();
qDebug() << "Temp file path:" << tempFile.fileName();
}
// 带特定后缀的临时文件
QTemporaryFile tempFileWithSuffix("prefix_XXXXXX.suffix");
if(tempFileWithSuffix.open()) {
// 使用临时文件
}
3. 原子写入操作(QSaveFile)
QSaveFile file("important.dat");
if(file.open(QIODevice::WriteOnly)) {
QDataStream out(&file);
out << "Critical data";
// 只有commit()成功才会替换原文件
if(!file.commit()) {
qDebug() << "Save failed:" << file.errorString();
}
}
跨平台注意事项
路径分隔符:始终使用
/
,QT会自动转换为平台正确的分隔符路径大小写:Windows不敏感,Linux/Mac敏感
标准路径:使用
QStandardPaths
获取标准目录
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString docPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
QString tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
错误处理
QFile file("nonexistent.txt");
if(!file.open(QIODevice::ReadOnly)) {
switch(file.error()) {
case QFile::ReadError:
qDebug() << "Read error:" << file.errorString();
break;
case QFile::PermissionsError:
qDebug() << "Permission denied:" << file.errorString();
break;
default:
qDebug() << "Error:" << file.errorString();
}
}
性能提示
处理大文件时避免使用
readAll()
,改为分块读取批量文件操作考虑使用
QDirIterator
提高效率频繁访问的文件信息可以缓存
QFileInfo
对象
// 高效遍历大目录
QDirIterator it("/path/to/dir", QDirIterator::Subdirectories);
while(it.hasNext()) {
qDebug() << it.next();
}