rust - 将文件名收集到 `Vec<str>`中

标签 rust

如何从目录收集文件名到Vec<&str>之类的文件中:

let paths = fs::read_dir("...")
    .unwrap()
    .filter_map(|e| e.ok())
    .map(|e| e.path().to_str());
另外,如果文件夹不存在,如何使其返回空列表?

最佳答案

fs::read_dir 返回在 Result<DirEntry> 上进行迭代的迭代器,该迭代器公开了 DirEntry::path 方法。此方法返回 PathBuf ,它拥有包含文件名的缓冲区。
在您的原始样本中,您尝试将它们转换为&str-这样做有两个问题:

  • path()返回一个PathBuf,您可以通过to_str()引用它,但是您没有将PathBuf存储在任何地方,因此编译失败,并显示以下错误:
  • error[E0515]: cannot return value referencing temporary value
     --> src/main.rs:7:18
      |
    7 |         .map(|e| e.path().to_str());
      |                  --------^^^^^^^^^
      |                  |
      |                  returns a value referencing data owned by the current function
      |                  temporary value created here
    
  • to_str()返回Option<str>-如果路径包含任何非UTF8字符,则它返回None。您最终将得到一个包含VecOption<&str>

  • 我建议将它们收集到Vec<PathBuf>中,它很简单:
        let paths = fs::read_dir("...")
            .unwrap()
            .filter_map(|e| e.ok())
            .map(|e| e.path())
            .collect::<Vec<_>>();
    
    如果确实需要它们作为字符串,则可以使用:
        let paths = fs::read_dir("...")
            .unwrap()
            .filter_map(|e| e.ok())
            .map(|e| e.path().to_string_lossy().into_owned())
            .collect::<Vec<_>>();
    
    to_string_lossy()将路径转换为字符串,并用替换字符替换所有非utf8字符。它返回Cow<&str>-可能实际上不拥有该字符串。为了确保返回拥有的字符串,我们调用into_owned()
    最后,如果文件夹不存在,则使其返回一个空列表,您可以使用如下所示的内容:
        let paths : Vec<PathBuf> = match fs::read_dir("/tmsp") {
        
            Err(e) if e.kind() == ErrorKind::NotFound => Vec::new(),
            
            Err(e) => panic!("Unexpected Error! {:?}", e),
            
            Ok(entries) => entries.filter_map(|e| e.ok())
                .map(|e| e.path())
                .collect()
                
    
        };
    
    如果发生除NotFound之外的任何其他错误,以上示例将引起 panic -实际上,您可能会更优雅地处理该情况。

    关于rust - 将文件名收集到 `Vec<str>`中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66577339/

    相关文章:

    multithreading - 使用 serde_json::from_str 反序列化为带有 &'static 字符串的结构存在生命周期错误

    loops - 为什么不更新使用 cycle() 创建的迭代器的可变值,导致无限循环,尽管有停止条件?

    rust - 如何从 Rust 中的 crate 为整个程序设置目标三元组?

    rust - 如何在Rust中将变量作为字符串文字传递?

    rust - 为什么我的变量生命周期不够长?

    rust - 为什么我不能借用我所借的东西,为什么我可以移动方法的自身?

    rust - 带有指向自身数据的切片的结构

    linux - MIO EventLoop 未针对 TcpStream 运行

    rust - Rust 中的字符串与选项匹配

    vector - RefCell中对数据的不变引用