在C++开发过程中,判断文件属性尤其是检查文件是否为只读状态,是文件操作相关的常见需求。无论是做文件管理工具、自动化脚本还是业务系统开发,都可能需要先确认文件的读写权限再执行后续操作。

使用C标准库函数判断(跨平台基础方案)
C标准库提供了_access函数(Windows平台)和access函数(Linux/Unix平台),可以用来检查文件的访问权限,通过判断写入权限是否存在,就能间接确认文件是否为只读。
Windows平台实现
Windows下的_access函数在<io.h>头文件中声明,第二个参数指定检查的权限类型,2表示检查写入权限,如果返回-1说明没有写入权限,文件为只读。
#include <iostream>
#include <io.h>
#include <cstring>
// 检查Windows平台下文件是否为只读
bool isFileReadOnlyWindows(const char* filePath) {
// 检查写入权限,返回0表示有写入权限,返回-1表示无写入权限(只读)
if (_access(filePath, 2) == -1) {
// 进一步确认文件是否存在,排除文件不存在的情况
if (_access(filePath, 0) == 0) {
return true;
}
}
return false;
}
int main() {
const char* testFile = "test.txt";
if (isFileReadOnlyWindows(testFile)) {
std::cout << testFile << " 是只读文件" << std::endl;
} else {
std::cout << testFile << " 不是只读文件" << std::endl;
}
return 0;
}
Linux/Unix平台实现
Linux平台下使用unistd.h中的access函数,逻辑和Windows平台类似,同样通过检查写入权限判断只读状态。
#include <iostream>
#include <unistd.h>
// 检查Linux平台下文件是否为只读
bool isFileReadOnlyLinux(const char* filePath) {
// 检查写入权限,返回0表示有权限,返回-1表示无权限(只读)
if (access(filePath, W_OK) == -1) {
// 确认文件存在
if (access(filePath, F_OK) == 0) {
return true;
}
}
return false;
}
int main() {
const char* testFile = "test.txt";
if (isFileReadOnlyLinux(testFile)) {
std::cout << testFile << " 是只读文件" << std::endl;
} else {
std::cout << testFile << " 不是只读文件" << std::endl;
}
return 0;
}
使用Windows API判断(Windows专属方案)
如果需要获取更完整的文件属性,Windows平台可以使用GetFileAttributes函数,该函数可以直接返回文件的所有属性标记,其中FILE_ATTRIBUTE_READONLY就是只读属性的标记。
#include <iostream>
#include <windows.h>
// 使用Windows API检查文件是否为只读
bool isFileReadOnlyByAPI(const char* filePath) {
// 获取文件属性
DWORD fileAttr = GetFileAttributes(filePath);
// 判断属性是否有效,且包含只读标记
if (fileAttr != INVALID_FILE_ATTRIBUTES && (fileAttr & FILE_ATTRIBUTE_READONLY)) {
return true;
}
return false;
}
int main() {
const char* testFile = "test.txt";
if (isFileReadOnlyByAPI(testFile)) {
std::cout << testFile << " 是只读文件" << std::endl;
} else {
std::cout << testFile << " 不是只读文件" << std::endl;
}
return 0;
}
跨平台C++17 filesystem方案
C++17引入了<filesystem>标准库,提供了跨平台的文件操作接口,可以通过权限状态判断文件是否为只读,不同平台下逻辑统一,不需要写条件编译代码。
#include <iostream>
#include <filesystem>
// 跨平台检查文件是否为只读(C++17及以上)
bool isFileReadOnlyCrossPlatform(const std::string& filePath) {
namespace fs = std::filesystem;
try {
// 获取文件状态
fs::file_status status = fs::status(filePath);
// 检查文件是否存在且为常规文件
if (fs::exists(status) && fs::is_regular_file(status)) {
// 获取权限,检查所有者、组、其他用户的写入权限
fs::perms permissions = status.permissions();
// 如果所有写入权限都没有,则为只读
bool hasWritePerm = (permissions & fs::perms::owner_write) != fs::perms::none ||
(permissions & fs::perms::group_write) != fs::perms::none ||
(permissions & fs::perms::others_write) != fs::perms::none;
return !hasWritePerm;
}
} catch (const fs::filesystem_error& e) {
std::cerr << "获取文件属性失败: " << e.what() << std::endl;
}
return false;
}
int main() {
std::string testFile = "test.txt";
if (isFileReadOnlyCrossPlatform(testFile)) {
std::cout << testFile << " 是只读文件" << std::endl;
} else {
std::cout << testFile << " 不是只读文件" << std::endl;
}
return 0;
}
不同方案对比
| 方案 | 跨平台性 | 依赖 | 适用场景 |
|---|---|---|---|
| C标准库函数 | 需要条件编译适配 | 基础C库 | 兼容旧标准,简单权限判断 |
| Windows API | 仅Windows | Windows系统库 | Windows平台需要完整属性信息 |
| C++17 filesystem | 完全跨平台 | C++17及以上标准 | 新项目,需要跨平台统一逻辑 |
实际开发中可以根据项目使用的C++标准、目标平台选择合适的方案,优先推荐C++17的filesystem方案,代码更简洁且跨平台性更好。