QT 文件和文件夹操作
文件操作
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();
}