QT 文件和文件夹操作

发布于:2025-04-19 ⋅ 阅读:(70) ⋅ 点赞:(0)

文件操作

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();
    }
}

跨平台注意事项

  1. 路径分隔符:始终使用/,QT会自动转换为平台正确的分隔符

  2. 路径大小写:Windows不敏感,Linux/Mac敏感

  3. 标准路径:使用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();
    }
}

性能提示

  1. 处理大文件时避免使用readAll(),改为分块读取

  2. 批量文件操作考虑使用QDirIterator提高效率

  3. 频繁访问的文件信息可以缓存QFileInfo对象

// 高效遍历大目录
QDirIterator it("/path/to/dir", QDirIterator::Subdirectories);
while(it.hasNext()) {
    qDebug() << it.next();
}

网站公告

今日签到

点亮在社区的每一天
去签到