鸿蒙PC中使用ohos-sdk完成Rust适配,自动签名编译安装第三方库walkdir是 Rust 递归遍历目录的专用库
欢迎加入开源鸿蒙PC社区 https://harmonypc.csdn.net/欢迎在PC社区平台申请新建项目https://atomgit.com/OpenHarmonyPCDeveloperAtomGit 仓库地址https://atomgit.com/OpenHarmonyPCDeveloper/ohos_rust_cargo本文讲解鸿蒙 PC 端 Rust 开发环境搭建鸿蒙基于 musl 库、强制二进制签名无法直接使用通用 Linux 编译产物。需借助鸿蒙专属包管理器 Harmonybrew提供两套编译方案方案一安装 llvm-gcc-compat零配置开箱即用方案二仅安装 ohos-sdk需手动配置 Cargo 链接器二者都依托 ohos-sdk 完成自动签名编译。完整的过程可以参考一下【OpenHarmony 鸿蒙 PC CodeArts IDE 实现 Rust开发完整开发环境搭建指南】一、walkdir 库介绍作用walkdir是 Rust 递归遍历目录的专用库比标准库std::fs::read_dir更强大、易用。核心能力递归遍历文件夹下所有文件子目录深度遍历过滤文件/目录、跳过隐藏文件、按后缀筛选.txt/.json等获取文件元信息大小、是否文件/文件夹、路径、修改时间控制遍历深度避免无限递归自动处理 IO 错误友好错误处理适用场景批量读取目录文件、日志扫描、文件批量处理、项目文件检索、本地文件同步、静态资源遍历。二、安装cargoaddwalkdirCargo.toml 自动添加[dependencies] walkdir 2三、完整无报错示例代码 main.rs包含 4 个常用场景基础遍历、只找指定后缀文件、限制遍历深度、过滤隐藏文件usewalkdir::{DirEntry,WalkDir};usestd::path::Path;fnmain(){// 1. 基础递归遍历当前目录所有文件和文件夹println!( 1. 递归遍历当前目录全部内容 );walk_all_dir(.);// 2. 只查找 .rs 源码文件println!(\n 2. 筛选所有rs源码文件 );find_file_by_suffix(.,.rs);// 3. 只遍历2层目录不深度递归println!(\n 3. 限制遍历深度最多2级 );walk_limit_depth(.,2);// 4. 过滤隐藏文件/隐藏文件夹以.开头println!(\n 4. 跳过所有隐藏文件 );walk_skip_hidden(.);}/// 基础递归遍历目录打印所有条目fnwalk_all_dir(root:str){// WalkDir::new 创建目录迭代器forentryinWalkDir::new(root).into_iter().flatten(){print_entry_info(entry);}}/// 按后缀筛选文件只输出普通文件跳过文件夹fnfind_file_by_suffix(root:str,suffix:str){letwalkerWalkDir::new(root).into_iter().flatten();forentryinwalker{// 只匹配普通文件跳过文件夹ifentry.file_type().is_file(){letpathentry.path();ifpath.extension().and_then(|s|s.to_str())Some(suffix.strip_prefix(.).unwrap()){println!(匹配文件: {},path.display());}}}}/// 限制最大遍历深度fnwalk_limit_depth(root:str,max_depth:usize){letwalkerWalkDir::new(root).max_depth(max_depth)// 限制层级.into_iter().flatten();forentryinwalker{print_entry_info(entry);}}/// 过滤隐藏文件/隐藏目录unix .开头文件fnwalk_skip_hidden(root:str){letwalkerWalkDir::new(root).into_iter().filter_map(|e|e.ok())// 忽略IO错误.filter(|e|{// 文件名不以 . 开头!e.file_name().to_str().map(|s|s.starts_with(.)).unwrap_or(false)});forentryinwalker{print_entry_info(entry);}}/// 打印一条目录条目的基础信息fnprint_entry_info(entry:DirEntry){letpathentry.path();letmetaentry.metadata().unwrap();letkindifmeta.is_dir(){文件夹}else{文件};println!([{}] 路径: {} | 大小: {} bytes,kind,path.display(),meta.len());}一、库简单回顾walkdir是 Rust 递归遍历文件夹的第三方库对比标准库std::fs::read_dir它原生支持递归、深度限制、过滤、错误自动处理是批量处理本地文件的首选工具。二、头部导入usewalkdir::{DirEntry,WalkDir};usestd::path::Path;WalkDir目录遍历核心迭代器用来开启文件夹扫描DirEntry遍历过程中每一个文件/文件夹的封装对象包含路径、文件类型、元数据、深度等信息std::path::Path标准库路径类型统一处理跨系统文件路径三、入口 main 函数fnmain(){// 1. 基础递归遍历当前目录所有文件和文件夹println!( 1. 递归遍历当前目录全部内容 );walk_all_dir(.);// 2. 只查找 .rs 源码文件println!(\n 2. 筛选所有rs源码文件 );find_file_by_suffix(.,.rs);// 3. 只遍历2层目录不深度递归println!(\n 3. 限制遍历深度最多2级 );walk_limit_depth(.,2);// 4. 过滤隐藏文件/隐藏文件夹以.开头println!(\n 4. 跳过所有隐藏文件 );walk_skip_hidden(.);}分4个场景演示最常用4种遍历逻辑完整递归扫描全部文件目录根据文件后缀筛选指定类型文件限制递归层级不无限下钻子文件夹过滤系统隐藏文件Linux/Mac 以.开头的文件如.git、.env四、函数1walk_all_dir 基础全量递归遍历fnwalk_all_dir(root:str){// WalkDir::new 创建目录迭代器forentryinWalkDir::new(root).into_iter().flatten(){print_entry_info(entry);}}WalkDir::new(root)传入根目录字符串.代表当前项目目录生成递归扫描器.into_iter()转为迭代器逐个产出目录条目.flatten()WalkDir迭代器产出ResultDirEntry, WalkDirErrorflatten 自动丢弃IO错误只保留正常读取到的文件等价于filter_map(|res| res.ok())循环遍历每一个DirEntry调用统一打印函数输出信息适用场景全盘扫描项目、读取目录下所有资源文件五、函数2find_file_by_suffix 按后缀筛选文件fnfind_file_by_suffix(root:str,suffix:str){letwalkerWalkDir::new(root).into_iter().flatten();forentryinwalker{// 只匹配普通文件跳过文件夹ifentry.file_type().is_file(){letpathentry.path();ifpath.extension().and_then(|s|s.to_str())Some(suffix.strip_prefix(.).unwrap()){println!(匹配文件: {},path.display());}}}}逐行拆解逻辑entry.file_type().is_file()判断当前条目是否为普通文件过滤掉文件夹、软链接只保留文件path.extension()获取文件后缀 OsStr例如main.rs后缀是rs.and_then(|s| s.to_str())将后缀转为字符串处理无后缀文件的空值suffix.strip_prefix(.).unwrap()传入参数是.rs去掉开头的.拿到纯后缀rs用于对比path.display()安全打印路径自动处理 Windows / Linux 不同路径分隔符调用示例find_file_by_suffix(., .rs)遍历当前目录只打印所有 Rust 源码文件六、函数3walk_limit_depth 限制递归深度fnwalk_limit_depth(root:str,max_depth:usize){letwalkerWalkDir::new(root).max_depth(max_depth)// 限制层级.into_iter().flatten();forentryinwalker{print_entry_info(entry);}}核心方法.max_depth(数字)根目录深度为0一级子文件夹深度1二级深度2示例传参max_depth2最多扫描两层不会读取三级及更深的子文件夹用途防止遍历超大嵌套目录、只需要浅层目录数据提升扫描速度补充配套API.min_depth(n)只遍历大于等于n层的文件跳过浅层目录.follow_links(true)跟随软链接默认关闭避免循环链接死递归七、函数4walk_skip_hidden 过滤隐藏文件fnwalk_skip_hidden(root:str){letwalkerWalkDir::new(root).into_iter().filter_map(|e|e.ok())// 忽略IO错误.filter(|e|{// 文件名不以 . 开头!e.file_name().to_str().map(|s|s.starts_with(.)).unwrap_or(false)});forentryinwalker{print_entry_info(entry);}}.filter_map(|e| e.ok())手动处理Result读取失败的目录直接丢弃e.file_name()获取当前条目文件名不含完整路径.map(|s| s.starts_with(.))判断文件名是否以.开头隐藏文件标记!取反只保留非隐藏文件和文件夹作用遍历项目时忽略.git、.vscode、.env等隐藏目录文件八、公共工具函数 print_entry_info 统一打印文件信息fnprint_entry_info(entry:DirEntry){letpathentry.path();letmetaentry.metadata().unwrap();letkindifmeta.is_dir(){文件夹}else{文件};println!([{}] 路径: {} | 大小: {} bytes,kind,path.display(),meta.len());}entry.path()获取完整路径对象entry.metadata()读取文件元数据大小、类型、修改时间、权限等meta.is_dir()区分文件夹 / 文件meta.len()文件字节大小文件夹统一返回0path.display()跨平台友好打印路径不会出现乱码九、DirEntry 高频内置方法汇总entry.path()// Path 完整路径entry.file_name()// OsStr 纯文件名entry.depth()// usize 当前目录层级深度entry.file_type()// 判断 文件/文件夹/软链接entry.metadata()// 文件元数据大小、修改时间entry.into_path()// 转为 Owned PathBuf十、整体业务使用场景批量读取日志文件夹下所有.log文件解析日志项目静态资源批量复制、压缩、重命名文件查重、统计目录总占用空间CLI工具扫描指定格式配置文件过滤隐藏目录只处理业务代码文件四、代码逐段详解1. 导入usewalkdir::{DirEntry,WalkDir};usestd::path::Path;WalkDir目录遍历生成器迭代器主体DirEntry每一条遍历结果包含路径、文件类型、元数据等信息2. 基础遍历WalkDir::new(root)WalkDir::new(.)传入根目录生成递归迭代器.into_iter().flatten()自动处理 IO 错误忽略读取失败目录等价于filter_map(|e| e.ok())3. DirEntry 常用方法entry.path()// Path 文件完整路径entry.file_name()// OsStr 文件名/文件夹名entry.file_type()// 判断是文件/目录/软链接entry.metadata()// 获取文件元数据大小、修改时间等entry.depth()// 当前相对根目录的层级深度4. 关键配置 APIWalkDir::new(path).max_depth(n)// 限制最大递归层级.follow_links(true)// 跟随软链接默认false不跟随防止循环.min_depth(n)// 最小遍历层级跳过浅层目录5. 文件后缀筛选逻辑path.extension().and_then(|s|s.to_str())Some(rs)获取文件后缀名字符串匹配目标后缀仅打印普通文件跳过文件夹。6. 跳过隐藏文件过滤文件名以.开头的条目Linux/Mac 隐藏文件如.git、.env五、极简高频片段可单独复制批量获取当前目录所有txt文件路径usewalkdir::WalkDir;fnget_all_txt()-VecString{letmutlistVec::new();forentryinWalkDir::new(.).flatten(){ifentry.file_type().is_file()entry.path().extension().unwrap_or_default()txt{list.push(entry.path().to_str().unwrap().to_string());}}list}获取目录下所有文件总大小usewalkdir::WalkDir;fncalc_dir_size(root:str)-u64{WalkDir::new(root).flatten().filter(|e|e.file_type().is_file()).map(|e|e.metadata().unwrap().len()).sum()}

相关新闻