用libuv实现遍历文件系统

news2024/11/17 2:28:54

熟悉的陌生人

Node.js可能无人不知无人不晓,但Node.js底层实现libuv,恐怕认识的同学就不多了。

libuv是一个跨平台的高性能的异步I/O库,也是是一个网络I/O扩展库,是一个高性能事件驱动的程序库,封装了Windows和Unix平台一些底层特性,为开发者提供了统一的API。它主要用于异步I/O,并且随着时间的推移,被广泛用于其他系统,如LuvitpyuvJulia等。可以处理大量并发连接,并且可以高效地利用系统资源,例如CPU和内存等。libuv提供了许多功能,例如TCP和UDP套接字、文件操作、DNS解析、线程池等。

重要的类型

uv_fs_t

uv_fs_t是libuv中用于文件系统操作的数据类型,它是一个结构体,用于存储文件系统操作的相关信息。libuv提供了许多文件系统操作的函数,例如uv_fs_open、uv_fs_read、uv_fs_write等,这些函数会接收一个uv_fs_t结构体作为参数,用于存储文件系统操作的状态和信息。

在进行文件系统操作时,libuv会将操作封装成一个任务,然后通过事件循环的方式来执行这个任务。当任务执行完成后,libuv会调用相应的回调函数来处理任务的结果。

一般情况下,libuv的文件系统操作是异步的,也就是说在执行文件系统操作时,程序不会阻塞等待操作完成,而是立即返回,然后在操作完成后调用相应的回调函数。这种异步操作的方式可以使得程序能够更高效地利用系统资源,提高程序的并发性能。回调函数设置为NULL就是同步调用。

uv_dirent_t

uv_dirent_t是libuv中用于表示目录条目的数据类型。它是一个结构体,用于存储目录中的文件或子目录的信息。

uv_dirent_t结构体中包含以下字段:

  1. name:目录条目的名称。
  2. type:目录条目的类型,可以是UV_DIRENT_FILE、UV_DIRENT_DIR、UV_DIRENT_LINK等。
  3. size:目录条目的大小,仅当type为UV_DIRENT_FILE时才有意义。
  4. time:目录条目的修改时间。

使用uv_dirent_t结构体可以遍历目录中的所有文件和子目录,获取它们的信息并进行相应的处理。libuv提供了uv_fs_scandir函数,用于遍历目录并返回一个uv_dirent_t结构体的数组,可以通过处理这个数组来获取目录中的所有文件和子目录的信息。

uv_dir_t

uv_dir_t是libuv中用于表示目录的数据类型。它是一个结构体,用于存储目录的路径和状态信息。

uv_dir_t结构体中主要包含以下字段:

  1. path:目录的路径。
  2. ptr:指向目录中第一个目录项的指针。
  3. flags:目录的标志,如UV_DIR_CLOSING等。
  4. rdbuf:目录项缓存区。
  5. rdbuf_size:目录项缓存区的大小。
  6. count:目录项的数量。
  7. fd:目录的句柄。

使用uv_dir_t结构体可以打开一个目录,并遍历其中的所有文件和子目录。libuv提供了uv_fs_opendir函数,用于打开一个目录并返回一个uv_dir_t结构体的指针。然后可以使用uv_dir_read函数来读取目录中的下一个目录项,获取它们的信息并进行相应的处理。当遍历完目录中的所有文件和子目录后,需要使用uv_dir_close函数来关闭目录。

开发方案

本文重点是libuv文件系统功能的实验,因为libuv源代码的编译不再描述。有兴起的同学可以参考libuv之64位编译方法和入门示例或使用vcpkg。vcpkg是微软C++团队开发的,适用于C++库的跨平台开源软件包管理器。它极大地简化了Windows、Linux和MacOS上第三方库的下载与配置操作,其优势在于自动下载开源库源代码、一键安装第三方库、源码包的缓存管理和版本管理,可以依需求安装指定的版本、自动检查库的依赖关系并安装其依赖项、无缝集成Visual Studio等。

遍历的实现逻辑

代码如下:

void read_dir(const std::string& zpath)
{
    uv_fs_t req_readdir;
    int iopen = uv_fs_opendir(NULL, &req_readdir, zpath.c_str(), NULL);
    if (iopen != 0)
    {
        std::cerr << hue::red << "open: " << zpath << ", error code: " << iopen << hue::white_on_black << std::endl;
        return;
    }
    uv_dirent_t dirent;
    uv_dir_t* dir = (uv_dir_t*)req_readdir.ptr;
    dir->dirents = &dirent;
    dir->nentries = 1;
    while (uv_fs_readdir(NULL, &req_readdir, dir, NULL))
    {
        if (dirent.type == UV_DIRENT_DIR)
        {
            std::string zsub_path = zpath + "\\" + dirent.name;
            read_dir(zsub_path);
        }
        std::cout << "name: " << zpath << "\\" << dirent.name << ", type: " << dirent.type << std::endl;
    }
    uv_fs_closedir(NULL, &req_readdir, dir, NULL);
}

zpath:目录的绝对路径,入口参数。此函数是一个递归函数,基本流程如下:

  1. 打开一个字符串表示的目上录。如失败则打印异常消息后返回。实现发现此类失败通常是失效的软链接。
  2. uv_dirent_t绑定,准备判断zpath下级返回的文件是否为目录。
  3. 循环读取目录。
    1. 如果uv_dirent_t告诉我们这是一个目录则拼接一个路径字符串,递归调用自己
    2. 打印路径信息。
  4. 关闭req_readdir,释放资源。

测试方法

CMakeList.txt

cmake_minimum_required(VERSION 3.20)
project(qqserialserver)
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>)
find_package(libuv CONFIG REQUIRED)
find_path(COLORCONSOLE_INCLUDE_DIRS "colorconsole.hpp")
add_executable(${PROJECT_NAME} main.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE libuv::uv)
target_include_directories(${PROJECT_NAME} PRIVATE ${COLORCONSOLE_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE $<IF:$<TARGET_EXISTS:libuv::uv_a>,libuv::uv_a,libuv::uv>)

main函数

#include <uv.h>
#include <colorconsole.hpp>
#include <cassert>

uv_loop_t* g_loop;

int main(int argc, char** argv)
{
    g_loop = uv_default_loop();
    uv_run(g_loop, UV_RUN_DEFAULT);
    read_dir("C:");
    uv_loop_close(g_loop);
    return 0;
}

程序运行结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1132947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】继承 ⑩ ( 继承机制中的 static 静态成员 | 子类中访问父类静态成员的方法 )

文章目录 一、继承机制中派生类中的 static 关键字1、子类继承父类静态成员2、父类静态成员访问控制权限的改变3、子类如何访问父类静态成员4、静态成员使用要点 二、完整代码示例 一、继承机制中派生类中的 static 关键字 1、子类继承父类静态成员 子类继承父类静态成员 : 父类…

Java商城免费搭建 VR全景商城 saas商城 b2b2c商城 o2o商城 积分商城 秒杀商城 拼团商城 分销商城 短视频商城

涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis …

基于Java+SpringBoot+MyBatis+Vue前后端分离宠物领养设计与实现

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

34二叉树-BFS和DFS求树的深度

目录 LeetCode之路——104. 二叉树的最大深度 分析 解法一&#xff1a;广度优先遍历 解法二&#xff1a;深度优先遍历 总结 深度优先搜索 (DFS) 广度优先搜索 (BFS LeetCode之路——104. 二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的…

渗透实战|通过社工进网站后台

通过社工进网站后台 记录一次通过简单社工获取信息后进入后台的经过。打开思路&#xff0c;利用我们所有能够捕获的信息并串联起来。 0X0 开始&#xff1a; 打开网站发现是一个登录网站 随便输入账号密码&#xff0c;发现有用户名枚举&#xff1a; 0X1 获取icp备案企业&…

CSS高级的详细解析

CSS高级 目标&#xff1a;掌握定位的作用及特点&#xff1b;掌握 CSS 高级技巧 01-定位 作用&#xff1a;灵活的改变盒子在网页中的位置 实现&#xff1a; 1.定位模式&#xff1a;position 2.边偏移&#xff1a;设置盒子的位置 left right top bottom 相对定位 posit…

四个小车相对导航集中式无迹卡尔曼滤波(fullyCN-EKF)

背景 二维情况下&#xff0c;四个小车各自有绝对定位&#xff08;GNSS&#xff09;&#xff0c;相互之间部分有相对定位&#xff08;UWB&#xff09;时&#xff0c;一个滤波器搞定四个小车的状态滤波。使用EKF。 建模 四个小车&#xff0c;每个有x、y两个轴&#xff0c;所以…

【网安大模型专题10.19】论文3:ChatGPT+自协作代码生成+角色扮演+消融实验

Self-collaboration Code Generation via ChatGPT 写在最前面朋友分享的收获与启发课堂讨论代码生成如何协作&#xff0c;是一种方法吗思路相同交互实用性 代码生成与自协作框架 摘要相关工作PPT学习大语言模型在代码生成方向提高生成的代码的准确性和质量&#xff1a;前期、后…

在 MaxPatrol SIEM 的帮助下,Positive Technologies 专家检测到影响超过 25 万用户的恶意软件

&#x1f468;‍&#x1f4bb; 从未经验证的来源下载软件&#xff1f;错误。从 torrent 跟踪器下载&#xff1f;致命错误。 八月份&#xff0c;我们的专家使用 MaxPatrol SIEM 在一家俄罗斯公司的网络中发现了异常活动。经过调查&#xff0c;CSIRT 团队&#xff08;Positive T…

useLayoutEffect和useEffect的区别

使用方式 这两个函数的使用方式其实非常简单&#xff0c;他们都接受一个函数一个数组&#xff0c;只有在数组里面的值改变的情况下才会再次执行 effect。所以对于使用方式我就不过多介绍了&#xff0c;不清楚的可以先参考官网 。 差异 useEffect 是异步执行的&#xff0c;而…

AOP和OOP有什么异同点

面向对象编程&#xff08;Object-Oriented Programming, OOP&#xff09;和面向切面编程&#xff08;Aspect-Oriented Programming, AOP&#xff09;是两种不同的编程范式&#xff0c;它们各自有着独特的目标和实现方式。下面我将列出它们的一些主要异同点&#xff1a; 相同点 …

基于嵌入式Qt 开发板蜂鸣器(BEEP)

## 简介 在GEC6818开发板,开发板板载资源上有一个蜂鸣器(BEEP)。如下图原理图。此蜂鸣器直接接在一个 GPIO 上,并不是接在 PWM 上,管脚资源限制。 ​ ## 示例 想要控制这个蜂鸣器(BEEP),首先我们出厂内核已经默认将这个 LED 注册成了 gpio-leds 类型设备。 项目简…

Java中JVM、JRE和JDK三者有什么区别和联系?

任何语言或者软件的运行都需要环境。就像人要生活在空气中&#xff0c;鱼要活在水中&#xff0c;喜阴植物就不能放在阳光下暴晒一样&#xff0c;任何对象个体的存在都离不开其所需要的环境&#xff0c;编程语言亦是一样的。 java 语言的开发运行&#xff0c;也离不开 Java 语言…

EtherCAT从站转CclinkIE协议网关应用案例

远创智控的YC-ECT-CCLKIE网关&#xff0c;一款具有强大功能的ETHERCAT通讯网关。 它可以将ETHERCAT网络和CCLINK IE FIELD BASIC网络无缝连接起来。作为ETHERCAT总线中的从站&#xff0c;本网关可以接收来自ETHERCAT主站的数据&#xff0c;并将其传输到CCLINK IE FIELD BASIC网…

【蓝桥杯选拔赛真题01】C++参赛建议 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析

目录 C/C++参赛建议 一、题目要求 1、编程实现 2、输入输出 二、算法分析 <

鲸鱼优化算法(Whale Optimization Algorithm,WOA)剖析

鲸鱼优化算法 鲸鱼优化算法&#xff08;Whale Optimization Algorithm&#xff0c;WOA&#xff09;是 2016 年由澳大利亚格里菲斯大学的 Mirjalili 等提出的一种新的群体智能优化算法&#xff0c;鲸鱼优化算法是一种用于解决优化问题的新型优化技术。该算法包括三个运算符&…

脏牛提权 liunx

使用方法 Liunx 普通用户 内核版本 在版本里 我直接脏牛提权 有脚本查看内核版本 上传c脚本 编译 直接执行 获取高权限 提权 Liunx https://github.com/InteliSecureLabs/Linux Exploit Suggester 运行这个脚本 上传到客户端 https://github…

cola架构:cola源码中访问者模式应用浅析

目录 1.访问者模式简介 2.cola访问者模式应用 2.1 cola被访问者类图 2.2 cola访问者类图 我们知道&#xff0c;如果一个对象结构包含很多类型的对象&#xff0c;希望对这些对象实施一些依赖其具体类型的操作&#xff0c;但又避免让这些操作“污染”这些对象的类&#xff0c…