Windows系统下C++检测.ini文件只读属性的问题咨询
如何在Windows下用C++检测.ini文件的只读属性
嘿,我懂你之前踩的那个坑——用ofstream以写入模式打开文件来检测只读,结果把.ini文件清空了,这太闹心了!别担心,给你两个靠谱的方案,都不会碰原文件的内容:
方法一:使用Windows原生API(推荐,最直接)
Windows系统自带的GetFileAttributesW函数可以直接获取文件属性,全程不需要打开文件,完全不会修改原内容,而且兼容性拉满:
#include <windows.h> #include <string> #include <iostream> // 检测文件是否为只读 bool isFileReadOnly(const std::wstring& filename) { // 获取文件属性,返回INVALID_FILE_ATTRIBUTES表示失败(比如文件不存在) DWORD fileAttrs = GetFileAttributesW(filename.c_str()); if (fileAttrs == INVALID_FILE_ATTRIBUTES) { std::cerr << "获取文件属性失败,错误码:" << GetLastError() << std::endl; return false; } // 按位与判断是否包含只读属性标志 return (fileAttrs & FILE_ATTRIBUTE_READONLY) != 0; } // 使用示例 int main() { std::wstring iniFilePath = L"C:\\YourPath\\config.ini"; if (isFileReadOnly(iniFilePath)) { std::cout << "该.ini文件是只读属性!" << std::endl; // 在这里执行你的操作 } else { std::cout << "该.ini文件不是只读属性。" << std::endl; } return 0; }
注意点:
- 用
std::wstring是因为GetFileAttributesW是宽字符版本,避免中文路径乱码问题;如果你的项目用多字节字符集,也可以用GetFileAttributesA搭配std::string。 - 这个函数不会修改文件,只是读取属性,完全安全。
方法二:使用C++17标准库filesystem(跨平台友好)
如果你希望代码以后能轻松移植到其他系统,C++17引入的<filesystem>库是更好的选择,同样不会修改文件:
#include <filesystem> #include <iostream> #include <string> namespace fs = std::filesystem; // 检测文件是否为只读 bool isFileReadOnly(const std::string& filename) { try { // 获取文件状态信息 fs::file_status fileStatus = fs::status(filename); // 判断:拥有者有读权限但没有写权限,即为只读(Windows下此逻辑生效) return (fileStatus.permissions() & fs::perms::owner_read) && !(fileStatus.permissions() & fs::perms::owner_write); } catch (const fs::filesystem_error& e) { std::cerr << "出错了:" << e.what() << std::endl; return false; } } // 使用示例 int main() { std::string iniFilePath = "C:\\YourPath\\config.ini"; if (isFileReadOnly(iniFilePath)) { std::cout << "该.ini文件是只读属性!" << std::endl; // 执行你的操作 } else { std::cout << "该.ini文件不是只读属性。" << std::endl; } return 0; }
注意点:
- 编译时需要开启C17及以上标准,比如在Visual Studio中,右键项目→属性→C/C→语言→C标准,选择C17或更高版本。
- 这个方法跨平台,以后如果要转到Linux/macOS也不用改逻辑。
为什么你之前的方法会清空文件?
你用ofstream ofs(filename)的时候,默认是std::ios::out模式,这个模式的行为就是截断文件(清空内容)并打开写入,所以才会把.ini文件搞没了内容。就算你改成std::ios::in | std::ios::out模式,也可能因为文件被占用等其他问题导致误判,远不如上面两种直接读取属性的方法可靠。
内容的提问来源于stack exchange,提问作者the_Begin
相关产品推荐
相关产品推荐

