赞
踩
- //遍历dir目录,找出修改日期距离当前超过age天的文件名称,存入file_list中
- fn visit_dir(dir: &Path, file_list: &mut Vec<String>, age: u64) -> io::Result<()> {
- if dir.is_dir() {
- for entry in fs::read_dir(dir)? {
- let entry = entry?;
- let path = entry.path();
- if path.is_dir() {
- visit_dir(&path, file_list, age)?;
- } else {
- let file_matedata = fs::metadata(entry.path()).unwrap();
- let modify_time = file_matedata.modified()?;
- if modify_time + Duration::from_secs(age * 24 * 60 * 60) < SystemTime::now(){
- file_list.push(entry.path().to_str().unwrap().to_string());
- }
- }
- }
- }
- Ok(())
- }
-
- //遍历dir目录,找出空目录(内部无文件,无目录)
- fn get_empty_dir(dir: &Path, dir_list: &mut Vec<String>) -> io::Result<()>{
- if !dir.is_dir() {
- return Ok(());
- }
- let read_dir = fs::read_dir(dir)?;
- let cnt = read_dir.count();
- if cnt == 0 {
- dir_list.push(dir.to_str().unwrap().to_owned());
- return Ok(());
- }
-
- let read_dir = fs::read_dir(dir)?;
- for entry in read_dir{
- let entry = entry?;
- let path = entry.path();
- if path.is_dir() {
- get_empty_dir(path.as_path(), dir_list)?;
- }
- }
- Ok(())
- }
上述函数实现比较直接,需要注意fs::read_dir()函数返回值后面的?宏,从read_dir返回值中提取结果。如visit_dir、get_empty_dir函数定义返回值不是io::Result类型,使用?宏,会报错。因为?宏还涉及错误传播,需要io::Result参与。
Rust的异步递归函数实现比较繁琐,为了简化,导入如下Crate:
async-recursion = "1.0.5"
- use async_recursion::async_recursion;
- #[async_recursion]
- async fn visit_dir_async(dir: &Path, file_list: &mut Vec<String>, age: u64) {
- if dir.is_dir() {
- //for entry in tokio::fs::read_dir(dir).flat_map().await? {
- let mut entries = tokio::fs::read_dir(dir).await.unwrap();
- while let Some(entry) = entries.next_entry().await.unwrap() {
- let path = entry.path();
- if path.is_dir() {
- visit_dir_async(&path, file_list, age).await;
- } else {
- let file_matedata = tokio::fs::metadata(entry.path()).await.unwrap();
- let modify_time = file_matedata.modified().unwrap();
- if modify_time + Duration::from_secs(age * 24 * 60 * 60) < SystemTime::now(){
- file_list.push(entry.path().to_str().unwrap().to_string());
- }
- }
- }
- }
- ()
- }
-
- #[async_recursion]
- async fn get_empty_dir_async(dir: &Path, dir_list: &mut Vec<String>) {
- println!("check path:{}", dir.to_str().unwrap());
- if !dir.is_dir() {
- return;
- }
- let mut read_dir = tokio::fs::read_dir(dir).await.unwrap();
- if let None = read_dir.next_entry().await.unwrap(){
- println!("find none path");
- dir_list.push(dir.to_str().unwrap().to_owned());
- return;
- }
- let mut read_dir = tokio::fs::read_dir(dir).await.unwrap();
- while let Some(entry) = read_dir.next_entry().await.unwrap(){
- let path = entry.path();
- if path.is_dir() {
- get_empty_dir_async(path.as_path(), dir_list).await;
- }
- }
- }
- use tokio::io::{self, BufReader, AsyncBufReadExt, BufWriter, AsyncWriteExt};
- use tokio::fs::{File, try_exists, remove_file, read_to_string, copy, read_dir};
- use std::path::{PathBuf};
-
- use std::fs::File as fsFile;
- use std::fs;
- use std::path::Path;
- use std::fs::{DirEntry};
- use std::time::{Duration, SystemTime};
-
-
- #[tokio::main]
- async fn main() -> io::Result<()> {
- let source_dir = "E:\\xxxxxx\\Log\\";
- //获取目录中的全部文件
- let mut file_list: Vec<String> = Vec::new();
- let path = Path::new(source_dir);
- visit_dir(path, &mut file_list, 30)?;
- for file in file_list{
- println!("{}", file);
- }
-
- let mut empty_file_list: Vec<String> = Vec::new();
- let path = Path::new(source_dir);
- get_empty_dir(path, &mut empty_file_list)?;
- for dir in empty_file_list{
- println!("{}", dir);
- }
-
- println!("====tokio==================================");
- let source_dir = "E:\\xxxxxx\\Log\\";
- //获取目录中的全部文件
- let mut file_list: Vec<String> = Vec::new();
- let path = Path::new(source_dir);
- visit_dir_async(path, &mut file_list, 30).await;
- for dir in file_list{
- println!("tokio {}", dir);
- }
- println!("====tokio==================================");
- let mut empty_file_list: Vec<String> = Vec::new();
- get_empty_dir_async(path, &mut empty_file_list).await;
- for dir in empty_file_list{
- println!("tokio {}", dir);
- }
- Ok(())
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。