Windows平台用CreateFile+ReadFile配合重叠I/O是最直接的异步文件读方案,需指定FILE_FLAG_OVERLAPPED标志、正确处理ERROR_IO_PENDING,并确保缓冲区生命周期覆盖整个操作;Linux/macOS无原生支持,通常用线程模拟,而std::filesystem和协程均不提供真正异步能力。

Windows平台用 CreateFile + ReadFile 配合重叠I/O是最直接的方案
Windows原生支持文件异步I/O,关键不是开新线程,而是用重叠(overlapped)机制让系统在后台完成读取后通知你。必须用 FILE_FLAG_OVERLAPPED 标志打开文件,否则 ReadFile 会退化为同步行为,即使传了 OVERLAPPED* 也会立即返回错误 ERROR_IO_PENDING 实际上是正常流程——说明操作已入队、尚未完成。
常见错误:忘记检查 CreateFile 返回值是否为 INVALID_HANDLE_VALUE;或调用 ReadFile 后没判断返回值和 GetLastError(),误以为失败就是出错,其实 ERROR_IO_PENDING 是预期状态。
- 文件句柄必须用
GENERIC_READ权限打开,并指定FILE_FLAG_OVERLAPPED -
OVERLAPPED结构体的hEvent字段可设为手动重置事件,用于等待;也可置空,改用GetOverlappedResult轮询或结合 I/O 完成端口 - 缓冲区生命周期必须覆盖整个异步操作周期——不能是栈变量且在
ReadFile返回后就销毁
Linux/macOS 没有原生文件异步I/O,得靠线程模拟
POSIX AIO(aio_read 等)在glibc中长期存在兼容性问题:多数文件系统不支持真正异步,最终还是走线程池模拟;而且接口复杂、错误码难调试、aiocb 必须全程有效。实际项目中,更可靠的做法是用 std::thread 或线程池封装 read() 调用。
注意:不要用 std::async(std::launch::async, ...) 直接包装 read(),因为默认策略可能复用线程,而阻塞式 read() 在慢设备(如NFS、加密盘)上会长时间占用线程资源,拖垮整个线程池。
立即学习“C++免费学习笔记(深入)”;
- 推荐显式创建分离线程,读完后通过回调函数或
std::promise传递结果 - 若需并发读多个文件,务必限制线程数(例如最多4–8个),避免系统级文件描述符或内存耗尽
- 对普通SSD本地文件,纯线程+阻塞读的吞吐和延迟并不比“伪异步”差,反而更可控
std::filesystem 不提供异步能力,别指望它
std::filesystem::read_bytes 和 std::filesystem::read_text 都是同步阻塞接口,底层调用的就是 read() 或 ReadFile()。试图在 std::jthread 里调用它们只是把同步操作挪到另一条线程,不是真正的异步I/O。
有人尝试用 std::coroutine 封装,但标准库无配套异步文件API,最终仍要落到平台API或线程调度上,徒增复杂度。
- 协程本身不等于异步I/O——它只是语法糖,底层驱动还得靠系统支持
- Boost.ASIO 的
asio::random_access_file支持 Linux 的io_uring(5.1+内核)和 Windows 的重叠I/O,但需要额外编译和运行时依赖 - 如果项目已用 Boost,且目标环境满足条件,
asio::random_access_file::async_read_some是目前最接近“标准C++异步文件读”的选择
跨平台抽象层容易掩盖性能陷阱
自己写一层“AsyncFileReader”类看似优雅,但很容易忽略平台差异带来的隐性成本:Windows重叠I/O要求缓冲区内存页锁定(VirtualLock)才能达到最佳性能;Linux线程模拟则受 /proc/sys/vm/max_map_count 限制;macOS 的 dispatch_io 已被标记为废弃。
真正需要异步文件读的场景其实很窄:比如游戏资源热加载、音视频流解包、日志归档服务。多数应用的“卡顿”根源不在文件读取本身,而在解析逻辑或内存拷贝——先用 perf 或 VTune 确认瓶颈再决定是否上异步。
- 小文件(mmap/
CreateFileMapping)往往更快,且无需管理异步状态 - 大文件顺序读,优先考虑预读(
posix_fadvise(POSIX_FADV_WILLNEED)/SetFileIoPriorityHint)而非异步 - 异步的价值在于“不阻塞主线程”,但代价是状态管理、错误传播、取消逻辑——这些比读文件本身难得多


















