如何阻止std::ofstream打开文件时自动创建不存在的文件
你写的测试代码里is_open()始终返回1,是因为你用了std::ofstream的默认打开模式,和方法本身的设计用途没有冲突。
默认打开模式的行为
std::ofstream调用open()时如果不主动指定打开模式,默认使用std::ios::out,该模式的规则就是文件不存在时自动创建,只要没有权限不足、路径非法、磁盘满这类异常情况,几乎每次都能打开成功,所以你测试时才会一直得到返回值1。
is_open()的实际作用
它的设计目的从来不是检查「目标文件在打开前是否已经存在」,而是用来确认当前文件流是否已经和某个文件成功绑定、可以正常执行后续读写操作,哪怕这个文件是刚被自动创建的,也算打开成功。
常见is_open()返回false的场景包括:
- 主动指定了不允许自动创建的打开模式,比如用
std::ios::in | std::ios::out模式打开,文件不存在时不会自动创建,返回0 - 目标文件被其他进程独占锁定,当前程序没有访问权限
- 传入的路径非法,比如包含系统不允许的特殊字符,或者路径对应的上级目录不存在
- 磁盘空间已满,无法创建新文件
- 程序对目标目录没有读写权限,比如普通权限的程序尝试在系统根目录创建文件
如果你需要检查文件是否预先存在
不要直接用默认模式的std::ofstream打开,两种常用实现方案:
- 用只读流打开检查,
std::ifstream默认不会自动创建文件:
#include <fstream> #include <iostream> int main() { std::ifstream checkFile("AAAAA.txt"); // 返回1代表文件存在,0代表不存在,不会自动创建文件 std::cout << checkFile.is_open(); }
- 用C++17新增的
std::ios::noreplace模式打开ofstream,文件不存在时不会自动创建:
#include <fstream> #include <iostream> int main() { std::ofstream f("AAAAA.txt", std::ios::out | std::ios::noreplace); // 返回1代表文件已存在且打开成功,0代表文件不存在/打开失败 std::cout << f.is_open(); }
内容的提问来源于stack exchange,提问作者TinCan
相关产品推荐
相关产品推荐

