V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Licsber
V2EX  ›  Rust

第一次学 Rust 写了个解压小工具 还挺爽

  •  
  •   Licsber · 113 天前 · 2767 次点击
    这是一个创建于 113 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求:递归 原地 解压所有压缩文件

    以前这种东西都用 python/shell 写

    现在正在试着全面转向 rust 的技术栈 反正 rustup 安装也挺方便的(但比 go 还是麻烦了点

    (好像设置 rust 和 rs 都没有代码高亮 凑活着看

    use std::env;
    use std::fs;
    use std::io;
    use std::path::{Path, PathBuf};
    use std::process::Command;
    
    fn unar_file(path: &Path) -> io::Result<()> {
        println!("UNAR: {}", path.display());
        let parent_dir = path.parent().unwrap();
        let filename = path.file_name().unwrap();
        let output = Command::new("unar")
            .current_dir(parent_dir)
            .arg("-s")
            .arg("-d")
            .arg(filename)
            .output();
    
        match output {
            Ok(res) => {
                if !res.status.success() {
                    eprintln!("Error processing compressed file {:?}: {}", path, String::from_utf8_lossy(&res.stderr));
                    return Err(io::ErrorKind::Other.into());
                }
            }
            Err(e) => {
                eprintln!("Failed to execute unar for {:?}: {}", path, e);
            }
        }
    
        Ok(())
    }
    
    fn is_compressed(path: &Path) -> bool {
        if let Some(ext) = path.extension() {
            if let Some(ext) = ext.to_str() {
                let ext = ext.to_lowercase();
                return ext == "zip" || ext == "rar" || ext == "7z";
            }
        }
    
        false
    }
    
    fn process_compressed_files(path: &Path) -> io::Result<()> {
        if !path.is_dir() {
            return Err(io::Error::new(io::ErrorKind::Other, "Not a directory"));
        }
    
        println!("Processing directory: {}", path.display());
        for entry in fs::read_dir(path)? {
            let entry_path = entry?.path();
            if entry_path.is_dir() {
                process_compressed_files(&entry_path)?;
            } else if is_compressed(entry_path.as_path()) {
                unar_file(&entry_path).expect("UNAR Error.");
            }
        }
    
        Ok(())
    }
    
    fn main() -> io::Result<()> {
        let args: Vec<String> = env::args().collect();
    
        let start_path = if args.len() > 1 {
            PathBuf::from(args[1].as_str())
        } else {
            PathBuf::from(".")
        };
    
        if start_path.is_file() {
            return unar_file(&start_path);
        }
    
        process_compressed_files(&start_path)?;
    
        Ok(())
    }
    

    不知道粗制滥造的代码有没有什么问题 Rust 大佬请指正~

    11 条回复    2024-09-08 23:34:45 +08:00
    yoiteshaw
        1
    yoiteshaw  
       113 天前   ❤️ 1
    rust 实现了把用户可能会遇到的麻烦,提前转移到了开发者身上。之前写完 python 还需要用户安装 python 环境,即使用 nuitka 打包,也是需要给用户提供一堆 dll 和库文件。

    写起来确实舒服。
    Licsber
        2
    Licsber  
    OP
       113 天前
    @yoiteshaw #1 对我来说 比 Python 好的点就是 不用源码交付 环境不这么难装
    况且心智负担 在业务场景我感觉不是什么大问题 对我来说很难用到高级特性 unsafe

    不过这么看其实 go 才最符合需求 哈哈哈 直接超简单的跨平台编译 小工具特别顺手
    但是 go 语法太简单了 有些人总喜欢要源码看看 就抄的很快 rust 让我更安心一点
    (至少 会 rust 的程序员 水平应该不至于写不出我写的一些小工具
    ((我不希望我的东西别人捡起来就能直接使用 这才是重点 hhhh
    yoiteshaw
        3
    yoiteshaw  
       113 天前   ❤️ 1
    @Licsber 我没学过 go ,rust 复杂的语法导致配合编译器能让编程者安心哈哈
    Licsber
        4
    Licsber  
    OP
       113 天前
    @yoiteshaw #3 哈哈哈 有点盲从了吧 不过确实有种安心的感觉
    因为听到的说法是 只要没乱用 unsafe 那能跑的代码差不多就是对的
    性能?性能后面再说(起码比 js 快吧
    shinyzhu
        5
    shinyzhu  
       113 天前 via iPhone   ❤️ 3
    我以为是那个“解压”
    bunny189
        6
    bunny189  
       113 天前 via iPhone   ❤️ 1
    @Licsber 哈哈哈哈哈,我也决定把我的 electron app 用 tarui 重构
    sunchuo
        7
    sunchuo  
       113 天前   ❤️ 1
    没看明白。为啥不直接用 unar ?
    Licsber
        8
    Licsber  
    OP
       113 天前
    @shinyzhu #5 哈哈哈 想了想确实 如果是为了解压来的 那应该升压了吧

    @bunny189 #6 万物 Rust 化 我也在入教中~

    @sunchuo #7 unar 只有写 shell 脚本 才可以原地解压所有压缩包吧
    有哪个命令可以不用 for 的情况下 直接解压全部 rar 和 zip 吗(
    需求就是 PT 下载了一个超大图包 而且很多子文件夹

    感觉这个代码的问题是没对文件结构做缓存
    导致解压后如果压缩包里还有压缩包 也会一起解压
    (不过这好像变成了特性?还挺好
    sunchuo
        9
    sunchuo  
       113 天前   ❤️ 1
    @Licsber -x -o ?
    momooc
        10
    momooc  
       113 天前   ❤️ 1
    tar.gz 、tar 、gz 等压缩包也支持一下吧
    Licsber
        11
    Licsber  
    OP
       113 天前
    @sunchuo #9 那还得写 for 呢 起码一个 for i in **/*.zip 吧 切换目录确实可以-o 太麻烦了

    @momooc #10 这个简单 判断函数里多加几个就行了 我记得 unar 也可以解压
    不过下载的图包一般没人用这些格式 所以不加也无所谓
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1367 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 17:20 · PVG 01:20 · LAX 09:20 · JFK 12:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.