如何通过Qt跨平台获取不可写入的已存在文件夹用于测试?
跨平台获取不可写入文件夹的Qt实现方案
嘿,这个需求我刚好有过类似的实践经验,给你整理了一套跨平台的Qt实现方案,分两种场景来处理,完美适配你的测试用例需求:
一、优先用系统自带的不可写入目录
每个操作系统都有默认的普通用户无写入权限的系统目录,我们可以用Qt的QStandardPaths来获取这些路径,同时加个验证确保真的不可写入:
- Windows:比如
C:\Windows\System32这类系统核心目录,普通用户默认没权限写入; - Linux/macOS:像
/usr/bin(Linux)、/System/Library(macOS)这类系统级目录,普通用户也没有写入权限。
对应的代码实现:
#include <QStandardPaths> #include <QFile> #include <QDebug> QString getSystemReadOnlyDir() { // 先尝试获取系统根目录 QString sysDir = QStandardPaths::writableLocation(QStandardPaths::SystemLocation); // 验证是否真的不可写入:尝试创建临时文件 QFile testFile(sysDir + "/test_write_perm.tmp"); if (!testFile.open(QIODevice::WriteOnly)) { return sysDir; } else { // 能写入就删掉文件,换系统bin目录试试 testFile.remove(); sysDir = QStandardPaths::writableLocation(QStandardPaths::SystemBinLocation); QFile testFile2(sysDir + "/test_write_perm.tmp"); if (!testFile2.open(QIODevice::WriteOnly)) { return sysDir; } testFile2.remove(); // 如果连系统目录都能写(比如管理员权限运行),就返回空,我们再走创建临时目录的逻辑 return QString(); } }
二、创建临时只读文件夹(应对特殊权限场景)
如果你的测试程序是用管理员/root权限运行的,系统目录可能能写入,这时候我们可以创建一个临时文件夹,再修改它的权限为不可写入,Qt结合系统命令就能实现:
#include <QTemporaryDir> #include <QFileInfo> #include <QProcess> QString createReadOnlyTempDir() { QTemporaryDir tempDir; if (tempDir.isValid()) { QString dirPath = tempDir.path(); // 不同系统修改权限的方式不一样,分情况处理 #ifdef Q_OS_WINDOWS // Windows用icacls命令禁止当前用户写入 QProcess process; process.start("icacls", QStringList() << dirPath << "/deny" << "%USERNAME%:(W)"); process.waitForFinished(); if (process.exitCode() == 0) { // QTemporaryDir会在程序退出时自动清理,直接返回路径就行 return dirPath; } #elif defined(Q_OS_LINUX) || defined(Q_OS_MACOS) // Linux/macOS用chmod把用户写入权限去掉 QFileInfo dirInfo(dirPath); if (dirInfo.permissions() & QFile::WriteUser) { bool success = dirInfo.setPermissions(QFile::ReadUser | QFile::ExeUser | QFile::ReadGroup | QFile::ExeGroup | QFile::ReadOther | QFile::ExeOther); if (success) { return dirPath; } } #endif } // 创建失败返回空 return QString(); }
三、通用的不可写入验证方法
不管是用系统目录还是临时创建的,都建议在测试前验证一下目录确实不可写入,避免因为权限特殊情况导致测试用例失效:
bool isDirNotWritable(const QString& dirPath) { QFile testFile(dirPath + "/test_write_validation.tmp"); bool canWrite = testFile.open(QIODevice::WriteOnly); if (canWrite) { testFile.remove(); return false; } return true; }
实际使用建议
- 测试时优先调用
getSystemReadOnlyDir,拿到路径后用isDirNotWritable验证,没问题就直接用,这样更贴近真实用户的使用场景; - 如果系统目录可写入(比如管理员权限),再调用
createReadOnlyTempDir创建临时只读目录; - 测试完成后,临时目录会自动清理,不用手动处理,非常方便。
内容的提问来源于stack exchange,提问作者Kamil Zaripov
相关产品推荐
相关产品推荐

