首页 > 其他分享 >libuv文件系统

libuv文件系统

时间:2024-05-09 09:56:36浏览次数:8  
标签:write uv read req 文件系统 pipe fs libuv

  1、读取和写入文件

  如下为异步打开test.dat文件后,读取文件数据并将其写入到标准输出的示例,读取和写入的时候使用uv_buf_t类型来作为缓存:

#include "uv.h"
#include <assert.h>

uv_fs_t open_req, read_req, write_req;

void on_write(uv_fs_t* req) {
    if (req->result < 0) {
        fprintf(stderr, "Write error: %s\n", uv_strerror((int)req->result));
    }
    else {
        fprintf(stdout, "\nComplete: %d characters written\n", req->result);
    }
}

void on_read(uv_fs_t* req) {
    if (req->result < 0) { //error:uv_fs_t::result域为读取的数据量或错误码
        fprintf(stderr, "Read error: %s\n", uv_strerror(req->result));
    }
    else if (req->result == 0) { //读取到文件末尾
        uv_fs_t close_req;
        uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL); 
        if (req->data)
            free(req->data);
    }
    else if (req->result > 0) { //读取到数据
        if (req->data) {
            auto iov = uv_buf_init((char*)(req->data), req->result);
            write_req.data = iov.base;
            uv_fs_write(uv_default_loop(), &write_req, 1/*标准输出*/, &iov, 1, -1, on_write);
        }
    }
}

void on_open(uv_fs_t* req)
{
    assert(req == &open_req);

    if (req->result >= 0) { //打开正常:uv_fs_t::result域为打开文件的fd(文件描述符)/ handle(句柄)
        int size = 1024; 
        auto iov = uv_buf_init((char*)malloc(size), size); //保存读取到的数据
        read_req.data = iov.base; //handle和request都有一个data域,可以用来存储上下文信息
        uv_fs_read(uv_default_loop(), &read_req, req->result, &iov, 1, -1, on_read);
    }
    else { //error
        fprintf(stderr, "error opening file: %s\n", uv_strerror((int)req->result)); //uv_strerror()可以获取错误信息,uv_err_name()可以获取错误名字
    }
}

int main()
{
    //int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb)
    //参数flags与mode和标准的 Unix flags 相同,对应Windows,libuv会自动将参数转换为 Windows 环境下的相关标志位(flags)
    uv_fs_open(uv_default_loop(), &open_req, "test.dat", O_RDWR, 0, on_open/*文件打开的回调*/); //文件操作方法如果不指定回调的话操作则为同步模式
    uv_run(uv_default_loop(), UV_RUN_DEFAULT);

    //清理内存
    uv_fs_req_cleanup(&open_req);
    uv_fs_req_cleanup(&read_req);
    uv_fs_req_cleanup(&write_req);
}

  除了uv_fs_open()、uv_fs_read(),libuv还提供uv_fs_stat()、uv_fs_mkdir()、uv_fs_access()等文件或目录的操作方法。libuv还提供了监视文件和文件夹的变化的相关api,具体可以参考 File change events

2、流式操作

  也可以使用流式操作来进行读取或写入操作,通过uv_read_start()、uv_write()、uv_read_stop()方法,调用uv_read_start()后会读取数据直到可读数据为空或uv_read_stop()被调用。TCP套接字,UDP套接字,管道支持流式操作,可以为文件关联一个pipe来对文件进行uv_read_start()、uv_write()流式操作。如下分别为test.dat文件和标准输出关联了一个pipe管道,然后对文件进行读取,读取到数据后将其写入到标准输出。实际运行代码发现将管道关联到文件的方法会报错,原因不得而知:

#include "uv.h"
#include <assert.h>

uv_pipe_t stdout_pipe, file_pipe;

void on_stdout_write(uv_write_t* req, int status) {
    free(req->data);
    free(req);
}

void on_read_file(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
    if (nread > 0) { //读取到数据
        uv_write_t* req = (uv_write_t*)malloc(sizeof(uv_write_t));
        auto iov = uv_buf_init((char*)malloc(nread), nread);
        memcpy(iov.base, (*buf).base, nread);
        iov.len = nread;
        req->data = iov.base;
        uv_write(req, (uv_stream_t*)&stdout_pipe, &iov, 1, on_stdout_write/*写入数据回调*/);
    }
    else if (nread < 0) { //读取到结尾或发生错误
        if (nread == UV_EOF/*end of file*/ || nread == UV_ENOBUFS/*alloc_buf() returned a buffer of length 0*/) {
            uv_close((uv_handle_t*)&stdout_pipe, NULL);
            uv_close((uv_handle_t*)&file_pipe, NULL);
        }
    }
    else {
        //there is no more reading left
    }

    if (buf->base)
        free(buf->base);
}

void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
    *buf = uv_buf_init((char*)malloc(suggested_size), suggested_size);
}

int main()
{
    uv_loop_t* loop = uv_default_loop();

    uv_fs_t file_req;
    int fd = uv_fs_open(loop, &file_req, "test.dat", O_CREAT | O_RDWR, 0644, NULL/*回调为空表示同步模式*/);

    auto i = uv_pipe_init(loop, &file_pipe, 1); //创建有名管道
    auto n = uv_pipe_open(&file_pipe, fd); //将管道和文件描述符关联起来,文件描述符会自动设为非阻塞

    uv_pipe_init(loop, &stdout_pipe, 0);
    uv_pipe_open(&stdout_pipe, 1/*标准输出*/);
    
    auto r = uv_read_start((uv_stream_t*)&file_pipe, alloc_buffer/*提供保存读取到数据的缓存uv_buf_t的方法*/, on_read_file/*读取到数据的回调*/); 
    uv_run(loop, UV_RUN_DEFAULT);
}

 

标签:write,uv,read,req,文件系统,pipe,fs,libuv
From: https://www.cnblogs.com/milanleon/p/18181451

相关文章

  • libuv概述
    1、综述  libuv是一个高性能的,事件驱动的I/O库,支持跨平台(由平台决定使用libev或IOCP),诞生自node.js。libev是网络库libevent的改进版,但libev在Windows下的性能不太好(使用select模型),而libuv则封装了Windows上的IOCP,性能更高,所以后来node.js使用libuv替换了libev。除了node.js以外......
  • Linux文件系统-目录
    如果你最开始使用的是Windows电脑,你很可能会使用“文件夹folder”这个术语。但当你换到Linux时,你会发现文件夹通常被称为“目录directory”。事情是这样的。如果你愿意,你可以叫它文件夹,如果你喜欢,也可以叫它目录。这没有什么区别。但是,如果你想知道为什么文件夹在Linux中......
  • FAT32和NTFS文件系统的区别
    FAT32和NTFS文件系统的区别今天学习到了文件IO方面,知道了在Linux中使用命令mkdir创建的并不是文件夹而是目录,有很多人喜欢将此认为是文件夹,严格意义上俩者是有很大的不同,今天通过查询资料得知俩者的区别,希望一下对于疑惑的你有所帮助。目录FAT32和NTFS文件系统的区别文件系统的......
  • fAT32文件系统与NTFS文件系统的区别
    FAT32文件系统FAT32(FileAllocationTable32)是一种较为古老的文件系统,它最初被设计用于MS-DOS和早期版本的Windows操作系统。FAT32文件系统的主要特点包括:兼容性:FAT32文件系统因其简单性而在多种操作系统和设备上得到了广泛的支持,包括Windows、MacOS和Linux等。文件大小限制:F......
  • FAT32和NTFS文件系统的区别
    *FAT32和NTFS的区别*1、*现实应用中的区别:*Ntfs目前多用于台式机电脑、笔记本等大中型空间容量的磁盘。Fat32较多运用于u盘等小型磁盘。NTFS分区采用“日志式”的文件系统,这种格式会对u盘闪存储介质造成较大的负担,造成u盘的损坏。2、*磁盘分区容量的区别:*fat32在Win2000和X......
  • FAT32和NTFS文件系统的区别
        文件系统对于在计算设备上运行至关重要。因此,选择正确的文件系统变得很重要。FAT32和NTFS是两个具有显着差异的文件系统。1、磁盘分区容量区别NTFS可以支持的分区(如果采用动态磁盘则称为卷)大小可以达到2TB(2048GB),而Windows2000中的FAT32支持分区的大小最大为32G......
  • NTFS、exFAT、FAT32、Ext4文件系统的区别
    V1.02024年5月7日发布于博客园NTFS、exFAT、FAT32、Ext4文件系统的区别FAT(FileAllocationTable)FAT(FileAllocationTable,文件分配表)是1977年微软为DOS开发的管理软盘的文件系统。FAT文件系统的最早版本是FAT12,由于其管理的容量非常有限,后来又陆续开发了FAT16文件系统和F......
  • 三类文件系统的区别
    什么是文件系统文件系统是操作系统用于明确磁盘或分区上的文件的方法和数据结构;即在磁盘上组织文件的方法。也指用于存储文件的磁盘或分区,或文件系统种类。举个通俗的比喻,一块硬盘就像一个块空地,文件就像不同的材料,我们首先得在空地上建起仓库(分区),并且指定好(格式化)仓库对材料的......
  • 在Linux中,如何创建文件系统的备份?
    在Linux中创建文件系统备份的方法有很多,这里介绍几种常见的方法:1.使用tar命令tar(tapearchive)是一个常用的归档工具,可以用来创建文件和目录的备份。创建备份:sudotar-czvf/path/to/backup.tar.gz/path/to/directoryc代表创建归档。z代表用gzip压缩归档。v代表在......
  • Debian文件系统构建
    1、环境配置sudoaptinstallqemu-user-static-ysudoaptinstalldebootstrap-ymkdirDebian_rootfs2、Debian文件系统构建 第一阶段:使用华为镜像源抽取根文件系统        sudodebootstrap–foreign--verbose--arch=armhfbusterroot......