如何在不尝试以读模式打开文件的前提下简便检查文件是否存在?
如何判断
ab+模式打开的文件是否是新创建的 你提到的需求很合理——不想重复打开文件浪费资源,同时要区分文件是本次打开时新建的还是原本就存在的。结合Windows平台,这里有几个更便捷的方案:
方案1:先检查文件存在性,再打开(简单但需注意竞态)
这是最直观的方法,先判断文件是否存在,再用ab+模式打开。虽然存在极小的竞态风险(比如检查后到打开前,文件被其他进程删除/创建),但在大多数单线程或低并发场景下完全够用。
Python示例:
import os file_path = "your_file.bin" # 先检查文件是否存在 existed_before = os.path.isfile(file_path) # 用ab+模式打开文件 with open(file_path, 'ab+') as f: if existed_before: # 文件原本存在,执行冗长的读取逻辑 f.seek(0) # ab+模式默认指针在末尾,需要移到开头读取 content = f.read() # ... 你的处理逻辑 else: # 文件是本次新建的,跳过读取逻辑 print("文件是新创建的,无需读取")
C++示例(VS环境):
#include <iostream> #include <fstream> #include <filesystem> namespace fs = std::filesystem; int main() { std::string file_path = "your_file.bin"; bool existed_before = fs::exists(file_path); // 以二进制读写追加模式打开(对应ab+) std::fstream file(file_path, std::ios::binary | std::ios::in | std::ios::out | std::ios::app); if (!file.is_open()) { std::cerr << "打开文件失败" << std::endl; return 1; } if (existed_before) { // 文件原本存在,执行读取逻辑 file.seekg(0); // 移到文件开头 // ... 读取处理 } else { // 文件是新创建的,跳过读取 std::cout << "文件是新创建的,无需读取" << std::endl; } file.close(); return 0; }
方案2:利用Windows API直接判断(无竞态,更严谨)
如果需要彻底避免竞态条件,可以直接调用Windows原生API(比如CreateFile),它能在打开文件的同时告知你文件是新建的还是已存在的。
C++示例(VS环境):
#include <iostream> #include <windows.h> #include <fcntl.h> #include <io.h> int main() { LPCWSTR file_path = L"your_file.bin"; HANDLE hFile = CreateFileW( file_path, GENERIC_READ | GENERIC_WRITE, // 读写权限 FILE_SHARE_READ | FILE_SHARE_WRITE, // 共享权限 NULL, OPEN_ALWAYS, // 存在则打开,不存在则创建 FILE_ATTRIBUTE_NORMAL, NULL ); if (hFile == INVALID_HANDLE_VALUE) { std::cerr << "打开文件失败,错误码:" << GetLastError() << std::endl; return 1; } bool existed_before = false; DWORD last_error = GetLastError(); if (last_error == ERROR_ALREADY_EXISTS) { existed_before = true; std::cout << "文件原本已存在" << std::endl; } else if (last_error == ERROR_SUCCESS) { std::cout << "文件是本次新建的" << std::endl; } // 如果需要转成C++标准文件流使用: int fd = _open_osfhandle((intptr_t)hFile, _O_BINARY | _O_RDWR | _O_APPEND); std::fstream file(fd, std::ios::binary | std::ios::in | std::ios::out | std::ios::app); if (existed_before) { // 执行读取逻辑 file.seekg(0); // ... 处理内容 } file.close(); CloseHandle(hFile); return 0; }
Python示例(借助pywin32库):
如果你用Python,可以通过pywin32库调用Windows API:
import win32file import win32con import win32api import io file_path = "your_file.bin" handle = win32file.CreateFile( file_path, win32con.GENERIC_READ | win32con.GENERIC_WRITE, win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE, None, win32con.OPEN_ALWAYS, win32con.FILE_ATTRIBUTE_NORMAL, None ) if handle == win32file.INVALID_HANDLE_VALUE: print(f"打开文件失败,错误码:{win32api.GetLastError()}") else: last_error = win32api.GetLastError() existed_before = last_error == win32con.ERROR_ALREADY_EXISTS created_new = last_error == 0 # ERROR_SUCCESS # 将句柄转为Python文件对象 f = io.open(handle, 'ab+') if existed_before: f.seek(0) content = f.read() # ... 处理逻辑 else: print("文件是新创建的") f.close() win32file.CloseHandle(handle)
总结
- 如果场景简单,优先用方案1,代码简洁易维护;
- 如果需要严格避免竞态条件,选择方案2,直接借助Windows API获取准确状态。
内容的提问来源于stack exchange,提问作者Terrornado
相关产品推荐
相关产品推荐

