C++17中推荐使用std::filesystem::exists检查文件存在性,因其跨平台、语义清晰且安全;2. 对于旧标准,可选用std::ifstream(通用但隐含可读性检查)、stat(POSIX系统高效获取元数据)或GetFileAttributes(Windows原生支持);3. access函数因可移植性差、权限混淆及TOCTOU安全风险而不被推荐。

在C++中,要检查一个文件是否存在,现代且推荐的做法是使用C++17引入的
std::filesystem::exists
std::ifstream
stat
GetFileAttributes
access
对于C++文件存在性检查,我们有几种主要且更优的替代方案,它们各有侧重,适用于不同的C++标准版本和平台需求。
std::filesystem::exists
std::ifstream
stat
stat
GetFileAttributes
GetFileAttributes
access
说实话,每次看到有人还在用
access
首先是可移植性。
access
立即学习“C++免费学习笔记(深入)”;
其次是权限混淆。当你只想知道文件在不在,却用了
access
access
access
再者是安全性或竞态条件。这是一个经典问题,被称为“检查时用,使用时错”(Time-of-Check to Time-of-Use, TOCTOU)漏洞。你用
access
access
true
所以,与其用一个“多功能”但有副作用的工具来做一件简单的事情,不如选择一个更专一、更安全的方案。
std::filesystem::exists
如果你的项目已经拥抱了C++17或更新的标准,那么恭喜你,
std::filesystem::exists
它的用法非常直观:
#include <iostream>
#include <filesystem> // C++17
int main() {
    std::filesystem::path p = "my_file.txt"; // 可以是相对路径或绝对路径
    // std::filesystem::path p = "/path/to/my_file.txt";
    if (std::filesystem::exists(p)) {
        std::cout << "文件 " << p << " 存在。" << std::endl;
    } else {
        std::cout << "文件 " << p << " 不存在。" << std::endl;
    }
    // 也可以检查目录
    std::filesystem::path dir_p = "my_directory";
    if (std::filesystem::exists(dir_p) && std::filesystem::is_directory(dir_p)) {
        std::cout << "目录 " << dir_p << " 存在。" << std::endl;
    } else {
        std::cout << "目录 " << dir_p << " 不存在或不是目录。" << std::endl;
    }
    return 0;
}std::filesystem::exists
GetFileAttributes
stat
std::filesystem
std::error_code
exists
std::filesystem
is_regular_file
is_directory
file_size
remove
create_directory
我个人觉得,只要项目条件允许,毫不犹豫地选择
std::filesystem
stat
ifstream
当然,事情总没那么简单,不是所有项目都能立马升级到C++17。在这种情况下,我们仍然有可靠的替代方案。
1. std::ifstream
这是最“C++原生”的方法之一,也适用于任何C++标准。它的核心思想是:如果我能成功打开一个文件,那它肯定存在。
#include <iostream>
#include <fstream> // For std::ifstream
#include <string>
bool fileExistsWithIfstream(const std::string& filename) {
    std::ifstream file(filename);
    return file.good(); // 或者 file.is_open(); 或者 !file.fail();
}
int main() {
    if (fileExistsWithIfstream("another_file.txt")) {
        std::cout << "文件 another_file.txt 存在且可读。" << std::endl;
    } else {
        std::cout << "文件 another_file.txt 不存在或不可读。" << std::endl;
    }
    return 0;
}这个方法的优点是简单易懂,跨平台(因为
std::ifstream
file.good()
false
2. stat
在Unix-like系统上(Linux、macOS、BSD等),
stat
<sys/stat.h>
#include <iostream>
#include <sys/stat.h> // For stat
#include <string>
#include <errno.h>    // For errno
#include <cstring>    // For strerror
bool fileExistsWithStat(const std::string& filename) {
    struct stat buffer;
    // stat() 返回 0 表示成功,-1 表示失败
    // 如果失败,可以通过 errno 判断具体原因
    if (stat(filename.c_str(), &buffer) == 0) {
        // 文件存在
        // 还可以通过 buffer.st_mode 判断是文件还是目录等
        // S_ISREG(buffer.st_mode) 判断是否是普通文件
        // S_ISDIR(buffer.st_mode) 判断是否是目录
        return true;
    } else {
        // 文件不存在或其他错误
        if (errno == ENOENT) {
            // 文件或路径不存在
            return false;
        } else {
            // 其他错误,比如权限问题
            std::cerr << "stat error for " << filename << ": " << strerror(errno) << std::endl;
            return false; // 或者根据需求处理
        }
    }
}
int main() {
    if (fileExistsWithStat("/tmp/my_temp_file.txt")) { // 举例路径
        std::cout << "文件 /tmp/my_temp_file.txt 存在。" << std::endl;
    } else {
        std::cout << "文件 /tmp/my_temp_file.txt 不存在或发生错误。" << std::endl;
    }
    return 0;
}stat
ifstream
errno
缺点是平台依赖性,它不是C++标准库的一部分,虽然POSIX兼容的系统很多,但它在Windows上无法直接使用。
3. GetFileAttributes
在Windows平台上,对应的API是
GetFileAttributes
<windows.h>
#include <iostream>
#include <string>
#include <windows.h> // For GetFileAttributes
bool fileExistsWithGetFileAttributes(const std::string& filename) {
    DWORD attributes = GetFileAttributesA(filename.c_str()); // GetFileAttributesA for char*, GetFileAttributesW for wchar_t*
    // 如果文件不存在,或者路径无效,GetFileAttributes会返回INVALID_FILE_ATTRIBUTES
    return (attributes != INVALID_FILE_ATTRIBUTES);
}
int main() {
    if (fileExistsWithGetFileAttributes("C:\Windows\System32\notepad.exe")) { // 举例路径
        std::cout << "文件 C:\Windows\System32\notepad.exe 存在。" << std::endl;
    } else {
        std::cout << "文件 C:\Windows\System32\notepad.exe 不存在。" << std::endl;
    }
    return 0;
}GetFileAttributes
ifstream
缺点是完全不跨平台,代码只能在Windows上编译运行。
综上所述,选择哪种方案,最终还是要看你的项目需求、目标平台和C++标准版本。如果能用C++17,
std::filesystem::exists
stat
GetFileAttributes
std::ifstream
以上就是C++如何检查文件存在 access函数替代方案的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号