【Rust】文件系统
目录
一、读取文件的字符串行
二、避免读取写入同一文件
三、使用内存映射随机访问文件
四、过去 24 小时内修改过的文件名
五、查找给定路径的循环
六、递归查找重名文件
七、使用给定断言递归查找所有文件
八、跳过隐藏文件遍历目录
九、在给定深度的目录,递归计算文件大小
十、递归查找所有 png 文件
十一、忽略文件名大小写,使用给定模式查找所有文件
本文将介绍Rust的文件系统,涵盖文件读写、目录遍历,并给出代码示例。
一、读取文件的字符串行
我们向文件写入三行信息,然后使用 BufRead::lines 创建的迭代器 Lines 读取文件,一次读回一行。File 模块实现了提供 BufReader 结构体的 Read trait。File::create 打开文件 File 进行写入,File::open 则进行读取,代码如下:
use std::fs::File;
use std::io::{Write, BufReader, BufRead, Error};fn main() -> Result<(), Error> {let path = "lines.txt";let mut output = File::create(path)?;write!(output, "out")?;let input = File::open(path)?;let buffered = BufReader::new(input);for line in buffered.lines() {println!("{}", line?);}Ok(())
}
二、避免读取写入同一文件
对文件使用 same_file::Handle 结构体,可以测试文件句柄是否等同。在本实例中,将对要读取和写入的文件句柄进行相等性测试。
use same_file::Handle;
use std::fs::File;
use std::io::{BufRead, BufReader, Error, ErrorKind};
use std::path::Path;fn main() -> Result<(), Error> {let path_to_read = Path::new("new.txt");let stdout_handle = Handle::stdout()?;let handle = Handle::from_path(path_to_read)?;if stdout_handle == handle {return Err(Error::new(ErrorKind::Other,"You are reading and writing to the same file",));} else {let file = File::open(&path_to_read)?;let file = BufReader::new(file);for (num, line) in file.lines().enumerate() {println!("{} : {}", num, line?.to_uppercase());}}Ok(())
}
三、使用内存映射随机访问文件
使用 memmap 创建文件的内存映射,并模拟文件的一些非序列读取。使用内存映射意味着您仅需索引一个切片,而不是使用 seek 方法来导航整个文件。
Mmap::map 函数假定内存映射后的文件没有被另一个进程同时更改,否则会出现竞态条件。
use memmap::Mmap;
use std::fs::File;
use std::io::{Write, Error};fn main() -> Result<(), Error> {write!(File::create("content.txt")?, "My hovercraft is full of eels!")?;let file = File::open("content.txt")?;let map = unsafe { Mmap::map(&file)? };let random_indexes = [0, 1, 2, 19, 22, 10, 11, 29];assert_eq!(&map[3..13], b"hovercraft");let random_bytes: Vec<u8> = random_indexes.iter().map(|&idx| map[idx]).collect();assert_eq!(&random_bytes[..], b"My loaf!");Ok(())
}
四、过去 24 小时内修改过的文件名
通过调用 env::current_dir 获取当前工作目录,然后通过 fs::read_dir 读取目录中的每个条目,通过 DirEntry::path 提取条目路径,以及通过通过 fs::Metadata 获取条目元数据。Metadata::modified 返回条目自上次更改以来的运行时间 SystemTime::elapsed。Duration::as_secs 将时间转换为秒,并与 24 小时(24 * 60 * 60 秒)进行比较。Metadata::is_file 用于筛选出目录。
use error_chain::error_chain;use std::{env, fs};error_chain! {foreign_links {Io(std::io::Error);SystemTimeError(std::time::SystemTimeError);}
}fn main() -> Result<()> {let current_dir = env::current_dir()?;println!("Entries modified in the last 24 hours in {:?}:",current_dir);for entry in fs::read_dir(current_dir)? {let entry = entry?;let path = entry.path();let metadata = fs::metadata(&path)?;let last_modified = metadata.modified()?.elapsed()?.as_secs();if last_modified < 24 * 3600 && metadata.is_file() {println!("Last modified: {:?} seconds, is read only: {:?}, size: {:?} bytes, filename: {:?}",last_modified,metadata.permissions().readonly(),metadata.len(),path.file_name().ok_or("No filename")?);}}Ok(())
}
五、查找给定路径的循环
使用 same_file::is_same_file 检测给定路径的循环。例如,可以通过软连接(符号链接)在 Unix 系统上创建循环:
mkdir -p /tmp/foo/bar/baz
ln -s /tmp/foo/ /tmp/foo/bar/baz/qux
下面的实例将断言存在一个循环。
use std::io;
use std::path::{Path, PathBuf};
use same_file::is_same_file;fn contains_loop<P: AsRef<Path>>(path: P) -> io::Result<Option<(PathBuf, PathBuf)>> {let path = path.as_ref();let mut path_buf = path.to_path_buf();while path_buf.pop() {if is_same_file(&path_buf, path)? {return Ok(Some((path_buf, path.to_path_buf())));} else if let Some(looped_paths) = contains_loop(&path_buf)? {return Ok(Some(looped_paths));}}return Ok(None);
}fn main() {assert_eq!(contains_loop("/tmp/foo/bar/baz/qux/bar/baz").unwrap(),Some((PathBuf::from("/tmp/foo"),PathBuf::from("/tmp/foo/bar/baz/qux"))));
}
六、递归查找重名文件
在当前目录中递归查找重复的文件名,只打印一次。
use std::collections::HashMap;
use walkdir::WalkDir;fn main() {let mut filenames = HashMap::new();for entry in WalkDir::new(".").into_iter().filter_map(Result::ok).filter(|e| !e.file_type().is_dir()) {let f_name = String::from(entry.file_name().to_string_lossy());let counter = filenames.entry(f_name.clone()).or_insert(0);*counter += 1;if *counter == 2 {println!("{}", f_name);}}
}
七、使用给定断言递归查找所有文件
在当前目录中查找最近一天内修改的 JSON 文件。使用 follow_links 确保软链接(符号链接)像普通目录和文件一样被按照当前查找规则执行。
use error_chain::error_chain;use walkdir::WalkDir;error_chain! {foreign_links {WalkDir(walkdir::Error);Io(std::io::Error);SystemTime(std::time::SystemTimeError);}
}fn main() -> Result<()> {for entry in WalkDir::new(".").follow_links(true).into_iter().filter_map(|e| e.ok()) {let f_name = entry.file_name().to_string_lossy();let sec = entry.metadata()?.modified()?;if f_name.ends_with(".json") && sec.elapsed()?.as_secs() < 86400 {println!("{}", f_name);}}Ok(())
}
八、跳过隐藏文件遍历目录
递归下行到子目录的过程中,使用 filter_entry 对目录中的条目传递 is_not_hidden 断言,从而跳过隐藏的文件和目录。Iterator::filter 可应用到要检索的任何目录 WalkDir::DirEntry,即使父目录是隐藏目录。
根目录 "." 的检索结果,通过在断言 is_not_hidden 中使用 WalkDir::depth 参数生成。
use walkdir::{DirEntry, WalkDir};fn is_not_hidden(entry: &DirEntry) -> bool {entry.file_name().to_str().map(|s| entry.depth() == 0 || !s.starts_with(".")).unwrap_or(false)
}fn main() {WalkDir::new(".").into_iter().filter_entry(|e| is_not_hidden(e)).filter_map(|v| v.ok()).for_each(|x| println!("{}", x.path().display()));
}
九、在给定深度的目录,递归计算文件大小
通过 WalkDir::min_depth 和 WalkDir::max_depth 方法,可以灵活设置目录的递归深度。下面的实例计算了 3 层子文件夹深度的所有文件的大小总和,计算中忽略根文件夹中的文件。
use walkdir::WalkDir;fn main() {let total_size = WalkDir::new(".").min_depth(1).max_depth(3).into_iter().filter_map(|entry| entry.ok()).filter_map(|entry| entry.metadata().ok()).filter(|metadata| metadata.is_file()).fold(0, |acc, m| acc + m.len());println!("Total size: {} bytes.", total_size);
}
十、递归查找所有 png 文件
在路径任意部分使用 ** 模式,例如,/media/**/*.png 匹配 media 及其子目录中的所有 PNG 文件。
use error_chain::error_chain;use glob::glob;error_chain! {foreign_links {Glob(glob::GlobError);Pattern(glob::PatternError);}
}fn main() -> Result<()> {for entry in glob("**/*.png")? {println!("{}", entry?.display());}Ok(())
}
十一、忽略文件名大小写,使用给定模式查找所有文件
在 /media/ 目录中查找与正则表达模式 img_[0-9]*.png 匹配的所有图像文件。
一个自定义 MatchOptions 结构体被传递给 glob_with 函数,使全局命令模式下不区分大小写,同时保持其它选项的默认值 Default。
注:glob
是 glob command
的简写。在 shell 里面,用 *
等匹配模式来匹配文件,如:ls src/*.rs。
use error_chain::error_chain;
use glob::{glob_with, MatchOptions};error_chain! {foreign_links {Glob(glob::GlobError);Pattern(glob::PatternError);}
}fn main() -> Result<()> {let options = MatchOptions {case_sensitive: false,..Default::default()};for entry in glob_with("/media/img_[0-9]*.png", options)? {println!("{}", entry?.display());}Ok(())
}
相关文章:
【Rust】文件系统
目录 一、读取文件的字符串行 二、避免读取写入同一文件 三、使用内存映射随机访问文件 四、过去 24 小时内修改过的文件名 五、查找给定路径的循环 六、递归查找重名文件 七、使用给定断言递归查找所有文件 八、跳过隐藏文件遍历目录 九、在给定深度的目录࿰…...

mysql双主双从读写分离
架构图: 详细内容参考: 结果展示: 178.119.30.16(从)- master 178.119.30.17(从)- slave 由上述结果可以看出,产生了主备节点同时抢占VIP的问题(即脑裂问题)…...

postgresql-物化视图
postgresql-物化视图 物化视图创建物化视图刷新物化视图修改物化视图删除物化视图 物化视图 创建物化视图 postgresql使用create materialized view 语句创建视图 create materialized view if not exists name as query [with [NO] data];-- 创建一个包含员工统计信息的物化…...

多层神经网络和激活函数
多层神经网络的结构 多层神经网络就是由单层神经网络进行叠加之后得到的,所以就形成了层的概念,常见的多层神经网络有如下结构: 1)输入层(Input layer),众多神经元(Neuronÿ…...
Visual Studio Code键盘快捷键大全
Visual Studio Code键盘快捷键大全 前言导航快捷键编辑快捷键多光标快捷键终端快捷键调试快捷键文件管理快捷键Git快捷键代码格式化快捷键代码折叠快捷键工作区快捷键Markdown快捷键Zen模式快捷键窗口管理快捷键重构快捷键IntelliSense快捷键测试快捷键扩展快捷键 前言 欢迎来…...

新手学习笔记-----⽂件操作
目录 1. 为什么使⽤⽂件? 2. 什么是⽂件? 2.1 程序⽂件 2.2 数据⽂件 2.3 ⽂件名 3. ⼆进制⽂件和⽂本⽂件? 4. ⽂件的打开和关闭 4.1 流和标准流 4.1.1 流 4.1.2 标准流 4.2 ⽂件指针 4.3 ⽂件的打开和关闭 5. ⽂件的顺序读写 …...
LeetCode 251:展开二维向量
题目 Implement an iterator to flatten a 2d vector. Example: [1,2,3,4,5,6] [1,2,3,4,5,6] Follow up: As an added challenge, try to code it using only iterators in C++ or iterators in Java. 题解: 用两个index 分别记录list 的 index 和当前 list的element index. …...

练[BSidesCF 2020]Had a bad day
[BSidesCF 2020]Had a bad day 文章目录 [BSidesCF 2020]Had a bad day掌握知识解题过程关键paylaod 掌握知识 php伪协议进行文件包含,代码审计,strpos()函数会返回字符串在另一字符串中第一次出现的位置,如果没有找到则返回 FALSE&#…...

第十五章 类和对象——友元
生活中你的家有客厅(Public),有你的卧室(Private) 客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去 但是呢,你也可以允许你的好闺蜜好基友进去。 在程序里,有些私有属性 也想让类外特殊的一些…...

【数仓精品理论分析】能不能学大数据?
【数仓精品理论分析】能不能学大数据? 还能不能学大数据datapulse官网: 自身情况数据行业发展情况 还能不能学大数据 首先看到这个话题的时候,我是这样想的,能不能学大数据需要参考本人的自身情况【学历、年龄、决心、有没有矿或者…...
java复习-多态性
多态性 在Java中对于多态性由两种实现的模式: 方法的多态性 方法的重载:同一个方法名称可以根据传入的参数类型和个数的不同,进行不同的处理。 方法的覆写:同一个方法可能根据使用子类的不同,由不同的实现。 对象的…...

美团外卖优惠券小程序 美团优惠券微信小程序 自带流量主模式 带教程
小程序带举牌小人带菜谱流量主模式,挺多外卖小程序的,但是都没有搭建教程 搭建: 1、下载源码,去微信公众平台注册自己的账号 2、解压到桌面 3、打开微信开发者工具添加小程序-把解压的源码添加进去-appid改成自己小程序的 4、…...
编写IDEA插件,实现根据现有代码生成流程图
实现根据现有代码生成流程图的功能需要考虑以下几个步骤: 分析代码结构,获取代码中的变量声明、分支语句、循环语句等语句结构。 根据代码结构生成流程图的节点和边。 将生成的流程图展示在IDEA界面中。 下面逐一说明以上步骤的实现方法:…...

王杰国庆作业day6
服务器 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <my_head.h> #define PORT 2324 //端口号 #define IP "192.168.10.107" //本机IP int main(int argc, const char *argv[]) {sqlite3* d…...

【C语言】循环结构程序设计 (详细讲解)
前言:前面介绍了程序中常常用到的顺序结构和选择结构,但是只有这两种结构是不够的,还有用到循环结构(或者称为重复结构)。因为在日常生活中或是在程序所处理的问题中常常遇到需要重复处理的问题。 【卫卫卫的代码仓库】 【选择结构】 【专栏链…...

Spring的注解开发-注解原理解析-xml方式/注解方式组件扫描
目录 Spring注解的解析原理 xml配置组件扫描 注解方式配置组件扫描 原理图 yysy,没有搞太明白,真的复杂,欢迎大佬留言解惑 Spring注解的解析原理 使用Component等注解配置完毕后,要配置组件扫描才能使注解生效 xml配置组件扫…...

导出视频里的字幕
导出视频里的字幕 如何利用剪映快速提取并导出视频里的字幕 https://jingyan.baidu.com/article/c35dbcb0881b6fc817fcbcd2.html 如何快速提取视频中的字幕?给大家介绍一种简单高效又免费的提取方法。需要利用到“剪映”,以下是具体的操作步骤和指引&a…...

【KingbaseES】银河麒麟V10 ARM64架构_安装人大金仓数据库KingbaseES_V8R6(CentOS8)
🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁 🦄 个人主页——🎐开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的…...

【Vue】Vuex详解,一文读懂并使用Vuex
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《ELement》。🎯🎯 …...
第三章 C程序设计
常量与变量 常量:整型常量:如1000 实型常量:十进制小数 字符常量:?! 变量:变量必须先定义,后使用。 标识符:一个对象的名字。 浮点型数据 浮点型数据是用来表示具…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...