如何在 Rust 中获取未知的文件类型扩展名

How to fetch unknown filetype extensions in rust

嘿,所以我正在尝试用 Rust 制作一个自动文件排序程序。我需要它来读取用户下载文件夹中的文件名,然后相应地将文件移动到一个单独的文件夹(jpg png 到“图片”文件夹等)

我在获取和使用文件类型扩展名时遇到了一些问题;我已经找到了一种获取整个文件名但不过滤掉文件名的方法,所以它现在只是扩展名。

我知道这段代码不正确,目前无​​法编译,但这是我所追求的模糊想法的证明。我不确定它是否有可能至少生锈。

use std::{thread,fs, time::Duration, io::Write};
// use chrono::Utc;
// use colour::*;


fn cls(){
    print!("{esc}c", esc = 27 as char);
}

fn credits(){
    print!("{esc}c", esc = 27 as char);
    println!("Made by Xanthus");
    println!("Check out my other works at https://github.com/Xanthus58");
    println!("Email me at 'Xanthus58@protonmail.com'");
    println!("You can see more information on my website https://xanthus58.github.io/Xanthus58/");
    
    let mut input = String::new();
    println!("Press Enter To Return");
    std::io::stdin().read_line(&mut input).unwrap();
    let minputod_yn = input.trim();
}

fn main() {
    loop{
        cls();
        let paths = fs::read_dir("./").unwrap();
        let mut file = "";
        for file_name in paths {
            let file_name = file_name.unwrap().path().display();
            //println!("Name: {}", file_name.unwrap().path().display());
            if file_name == ".jpg" || file_name == ".png"{
                let picture_dir = "Downloaded Pictures";
                fs::create_dir_all(picture_dir).unwrap();
                std::fs::rename(file_name, format!("{picture_dir}/{file_name}")).unwrap();
                println!("Name: {} Moved to {}", file_name.unwrap().path().display(), picture_dir)
            }
            else if file_name == ".mp4" || file_name == ".mkv"{
                let video_dir = "Downloaded Videos";
                fs::create_dir_all(video_dir).unwrap();
                std::fs::rename(file_name, format!("{video_dir}/{file_name}")).unwrap();
                println!("Name: {} Moved to {}", file_name.unwrap().path().display(), video_dir)
            }
            else if file_name == ".mp3" || file_name== ".ogg"{
                let music_dir = "Downloaded music";
                fs::create_dir_all(music_dir).unwrap();
                std::fs::rename(file_name, format!("{music_dir}/{file_name}")).unwrap();
                println!("Name: {} Moved to {}", file_name.unwrap().path().display(), music_dir)
            }
        }
    }
}

使用Path::extension获取文件扩展名。您可以使用 match 块将扩展名映射到文件夹。这有点尴尬,因为它 returns Option<&OsStr> 而不是 Option<&str>。我们不能编写与字符串文字的直接匹配,但我们可以使用它并使用 ==.

let entries = fs::read_dir("./").unwrap();
for entry in entries {
    let path = entry.unwrap().path();
    let file_name = match path.file_name() {
        Some(file_name) => file_name,
        None => continue,
    };
    let download_dir = match path.extension() {
        Some(ext) if ext == "jpg" => "Downloaded Pictures",
        Some(ext) if ext == "png" => "Downloaded Pictures",
        Some(ext) if ext == "mp4" => "Downloaded Videos",
        Some(ext) if ext == "mkv" => "Downloaded Videos",
        Some(ext) if ext == "mp3" => "Downloaded music",
        Some(ext) if ext == "ogg" => "Downloaded music",
        _ => continue,
    };
    let download_dir = Path::new(download_dir);
    
    fs::create_dir_all(download_dir).unwrap();
    fs::rename(&path, download_dir.join(file_name)).unwrap();
    println!("Name: {} Moved to {}", path.display(), download_dir.display());
}

其他改进:

  • 从匹配块中重构了公共代码。
  • 使用Path::join代替format!加入下载目录和文件名。