原始文件
asco::io::file
提供直接面向操作系统的文件读写接口(不进行用户态缓冲),基于协程的异步 API,适合需要精确控制 I/O 的场景。
要点
- 无用户态缓冲:请求直接提交到内核
- 异步接口:open/close/reopen/write/read 均为协程;read 可被打断并恢复,open/close/reopen/write 为不可打断的 inline future
- 独立读写指针:支持 seekg/seekp 与 tellg/tellp
- 可取得原生句柄以与其他系统 API 协作
- 与零拷贝缓冲区 buffer<> 协同良好
主要类型
file
:已打开文件的句柄file::options
:打开选项(位标志)opener
:链式配置的打开器(builder)open_file
:底层打开实现(返回future<std::expected<file,int>>
)read_result
:读取结果状态(eof
/interrupted
/again
)file_state
:文件状态视图(如size()
)
打开与关闭
创建打开器
file::at(path)
:基于路径创建opener
file::at()
:从现有file
的上下文创建opener
(便于reopen()
)
打开/关闭方法
future_inline<void> open(std::string path, flags<file::options> opts, uint64_t perm = 0)
future<void> close()
future_inline<void> reopen(opener&&)
注意
- 已打开对象再次
open()
将抛出异常 - 使用
create
选项时应提供perm
(如 0644) - 析构时若仍处于打开状态将自动
close()
示例
using asco::io::file;
using asco::flags;
auto r = co_await file::at("/tmp/data.log")
.write().append().create().exclusive()
.mode(0644)
.open();
if (!r) co_return; // r.error() 为 errno
file f = std::move(*r);
// 或:file f; co_await f.open("/tmp/data.log", flags{file::options::write}, 0644);
co_await f.close();
读写
写入
- 签名:
future<std::optional<buffer<>>> write(buffer<> buf)
(不可中止) - 语义:尽量写出
buf
,未全部写完则返回剩余数据;全部写尽返回std::nullopt
- 需以
options::write
打开
读取
- 签名:
future<std::expected<buffer<>, read_result>> read(size_t nbytes)
- 语义:读取至多
nbytes
,成功返回数据,否则返回eof
/interrupted
/again
- 需以
options::read
打开(可被中止)
示例:写到完成
asco::io::buffer<> buf("hello");
while (true) {
auto rest = co_await f.write(std::move(buf));
if (!rest) break;
buf = std::move(*rest);
}
示例:读到 EOF
std::string out;
for (;;) {
auto r = co_await f.read(4096);
if (!r) {
if (r.error() == asco::io::read_result::eof) break;
if (r.error() == asco::io::read_result::interrupted) continue;
if (r.error() == asco::io::read_result::again) { co_await std::suspend_always{}; continue; }
} else {
out += std::move(*r).to_string();
}
}
指针与状态
size_t seekg(ssize_t offset, seekpos whence = seekpos::current)
size_t seekp(ssize_t offset, seekpos whence = seekpos::current)
size_t tellg() const
size_t tellp() const
file_state state() const
(Linux:基于fstat()
)
说明
seekpos::begin
:offset
必须非负seekpos::end
:offset
必须非正seekpos::current
:允许正负偏移,但不得越界- 越界将抛出运行时错误
示例
f.seekp(0, asco::io::seekpos::end); // 追加写
auto pos = f.tellp();
f.seekg(0, asco::io::seekpos::begin);
原生句柄
raw_handle()
:返回底层原生句柄(Linux 为int
),可与系统 API 协作