libuv 采用了 异步 (asynchronous),事件驱动 (event-driven)的编程风格,其主要任务是为开人员提供了一套事件循环和基于I/O(或其他活动)通知的回调函数,libuv 提供了一套核心的工具集,例如定时器,非阻塞网络编程的支持,异步访问文件系统,子进程以及其他功能。
libuv对文件操作的函数都封装在uv_fs开头的函数中,相关的handle就是uv_fs_t/uv_fs_s,这里直接贴出来测试的代码,在本地进行编译后就可以很直观的看到效果。
这里的demo是将测试的字符串写入到指定文件中,当前也会显示到标准输出中(console)。
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
uv_loop_t* loop;
char test_buf[4096] = "hello world, this is a wonderful daa, thank oou!";
static uv_buf_t iov;
static uv_fs_t open_req;
static uv_fs_t read_req;
static uv_fs_t write_req;
static void write_cb(uv_fs_t* req);
static void read_cb(uv_fs_t* req);
static void write_cb2(uv_fs_t* req);
static void read_cb2(uv_fs_t* req);
static void create_cb(uv_fs_t* req)
{
iov = uv_buf_init(test_buf, sizeof(test_buf));
uv_fs_write(loop, &write_req, req->result, &iov, 1, -1, write_cb2);
}
static void write_cb(uv_fs_t* req)
{
if (req->result < 0) {
fprintf(stderr, "Write error: %s\n", uv_strerror((int)req->result));
} else {
uv_fs_read(loop, &read_req, open_req.result, &iov, 1, -1, read_cb);
}
}
static void read_cb(uv_fs_t* req)
{
if (req->result < 0) {
fprintf(stderr, "Read error: %s\n", uv_strerror(req->result));
} else if (req->result == 0) {
uv_fs_t close_req;
// synchronous
uv_fs_close(loop, &close_req, open_req.result, NULL);
} else if (req->result > 0) {
iov.len = req->result;
uv_fs_write(loop, &write_req, 1, &iov, 1, -1, write_cb);
}
}
static void write_cb2(uv_fs_t* req)
{
static int count = 0;
if (req->result < 0) {
fprintf(stderr, "Write error: %s\n", uv_strerror((int)req->result));
} else {
if (++count <= 3) {
for (int i = 0; i < iov.len; i++) {
iov.base[i] += 1;
}
uv_fs_write(loop, &write_req, open_req.result, &iov, 1, -1,
write_cb2);
} else {
uv_fs_t close_req;
uv_fs_close(loop, &close_req, open_req.result, NULL);
}
}
}
static void read_cb2(uv_fs_t* req)
{
if (req->result < 0) {
fprintf(stderr, "Read error: %s\n", uv_strerror(req->result));
} else if (req->result == 0) {
uv_fs_t close_req;
// synchronous
uv_fs_close(loop, &close_req, open_req.result, NULL);
} else if (req->result > 0) {
iov.len = req->result;
uv_fs_write(loop, &write_req, 1, &iov, 1, -1, write_cb);
}
}
static void open_cb(uv_fs_t* req)
{
if (req->result < 0) {
fprintf(stderr, "async open error: %d\n", (int)req->result);
}
// memset(buf, 0, sizeof(buf));
iov = uv_buf_init(test_buf, sizeof(test_buf));
uv_fs_read(loop, &read_req, req->result, &iov, 1, -1, read_cb);
}
int main(void)
{
loop = uv_default_loop();
// uv_fs_open(loop, &open_req, "fileops/main.c", O_RDONLY, 0, open_cb);
uv_fs_open(loop, &open_req, "fileops/fs_test.txt", O_WRONLY | O_CREAT,
S_IRUSR | S_IWUSR, create_cb);
return uv_run(loop, UV_RUN_DEFAULT);
}