C++如何区分文件是否存在:创建加头部或追加内容?
你提到的fstat确实能用来判断文件是否存在,但其实还有更贴合C++风格的方案,我给你整理几种可行的实现方式,按需选择就行:
方案1:用C++17 std::filesystem(推荐)
这是最现代、可读性最高的写法,适合支持C++17及以上的项目。核心思路是先判断文件是否存在,再分别处理创建+写头部、直接追加两种场景:
#include <fstream> #include <filesystem> namespace fs = std::filesystem; void write_with_header(const std::string& filename, const std::string& header, const std::string& content) { bool file_exists = fs::exists(filename); // 根据文件是否存在选择打开模式 std::ofstream file(filename, std::ios::out | (file_exists ? std::ios::app : std::ios::trunc)); if (!file.is_open()) { // 这里可以添加打开失败的错误处理,比如打印日志或抛出异常 return; } // 只有文件不存在时才写入头部 if (!file_exists) { file << header << '\n'; } // 追加内容 file << content << '\n'; file.close(); }
如果不想一次性打开文件,也可以拆成两步:先判断存在性,不存在就创建写头部,存在就直接追加,逻辑更直白:
#include <fstream> #include <filesystem> namespace fs = std::filesystem; void write_with_header(const std::string& filename, const std::string& header, const std::string& content) { if (!fs::exists(filename)) { std::ofstream new_file(filename); if (new_file.is_open()) { new_file << header << '\n' << content << '\n'; new_file.close(); } } else { std::ofstream append_file(filename, std::ios::out | std::ios::app); if (append_file.is_open()) { append_file << content << '\n'; append_file.close(); } } }
方案2:用POSIX的fstat/access函数(兼容旧标准)
如果你的项目没法用C++17,那可以用传统的POSIX API来判断文件存在性,比如你提到的fstat,或者更直接的access:
用access函数的写法
access可以直接检查文件是否存在,代码更简洁:
#include <fstream> #include <unistd.h> // 引入access函数 #include <errno.h> void write_with_header(const std::string& filename, const std::string& header, const std::string& content) { // 检查文件是否存在,F_OK表示只判断存在性 if (access(filename.c_str(), F_OK) != 0) { if (errno == ENOENT) { // 确认是文件不存在的情况,创建并写头部 std::ofstream new_file(filename); if (new_file.is_open()) { new_file << header << '\n' << content << '\n'; new_file.close(); } } else { // 处理其他错误,比如权限不足、路径无效等 // 这里可以添加错误日志 } } else { // 文件存在,直接追加 std::ofstream append_file(filename, std::ios::out | std::ios::app); if (append_file.is_open()) { append_file << content << '\n'; append_file.close(); } } }
用fstat函数的写法
如果你坚持用fstat,需要先尝试以只读方式打开文件,再通过fstat判断:
#include <fstream> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> void write_with_header(const std::string& filename, const std::string& header, const std::string& content) { struct stat file_info; int fd = open(filename.c_str(), O_RDONLY); if (fd == -1) { if (errno == ENOENT) { // 文件不存在,创建并写入头部和内容 std::ofstream new_file(filename); if (new_file.is_open()) { new_file << header << '\n' << content << '\n'; new_file.close(); } } else { // 处理其他打开错误 } } else { // 文件存在,获取文件信息后关闭文件描述符 fstat(fd, &file_info); close(fd); // 追加内容 std::ofstream append_file(filename, std::ios::out | std::ios::app); if (append_file.is_open()) { append_file << content << '\n'; append_file.close(); } } }
注意事项
- 不管哪种方案,都要记得处理文件打开失败的情况(比如磁盘满、权限不足),避免程序崩溃或静默失败
- 使用
std::filesystem时,GCC/Clang可能需要额外链接文件系统库:编译时加-lstdc++fs(GCC)或-lc++fs(Clang) - POSIX API的写法是平台相关的,Windows下需要替换成
_access、_open、_fstat等对应函数
内容的提问来源于stack exchange,提问作者dang92
相关产品推荐
相关产品推荐

