迭代 std::fs::ReadDir 并仅从路径中获取文件名 [英] Iterate over std::fs::ReadDir and get only filenames from paths

查看:53
本文介绍了迭代 std::fs::ReadDir 并仅从路径中获取文件名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试弄清楚如何使用 Rust 进行列表理解".我有一个 ReadDir 迭代器,我想映射它并且只获取路径的文件名.我认为它看起来像:

I'm trying to figure out how to do a 'list Comprehension' with rust. I have a ReadDir iter that I want to map and only get the filenames of the paths. I'm thinking it would look something like:

// get current dir paths
let paths = fs::read_dir(&Path::new(
    &env::current_dir().unwrap())).unwrap();

// should contain only filenames
let files_names = paths.map(|&x| {
    match (*x).extensions() {
        Some(y) => y,
        None => //What do I do here? break?
};

我知道我的表达式可能被严重破坏,但是有没有办法使它成为我可以将 file_names 绑定到的单个表达式?

I know my expression is likely horrendously broken, but is there a way to make this a single expression that I can bind file_names to?

推荐答案

您可能想要使用 Pathfile_name() 方法来生成文件名如果它是一个普通文件,这就是它返回一个Option的原因.

You'll probably want to use Path's file_name() method which yields the file name if it's a regular file, which is why it returns an Option.

我想你会想忽略非常规文件的文件名,即对于那些 file_name() 将返回 None,在这种情况下你可能想要利用 Iteratorfilter_map 方法,它基本上就像过滤器和地图放在一起,即你能够映射(在这种情况下是路径 ->文件名)并通过将映射结果作为 Option 返回来进行过滤,其中 None 表示您要过滤掉该值.

I imagine you'd want to ignore the file names of things that aren't regular files, i.e. for which file_name() would return None, in which case you will probably want to leverage Iterator's filter_map method which is basically like filter and map put together, i.e. you're able to map (in this case the path -> file name) and filter by returning the mapped result as an Option, where None would signify that you want to filter that value out.

烦人的事情是你必须检查 ReadDir 迭代器返回的每个项目,因为这是一个 Result 类型,所以你必须看看它是否是好的.如果您只想忽略目录中的非Ok(即Err)条目(例如您没有权限的条目),您可以简单地将其转换为一个 Option 使用 Resultok() 方法并将其集成到 filter_map 中.

The annoying thing will be that you have to check each item returned by the ReadDir iterator, since that's a Result type, so you'll have to see if it's Ok. If you just want to ignore non-Ok (i.e. Err) entries in the directory (e.g. entries for which you don't have permission), you can simply convert it to an Option using Result's ok() method and integrate that in the filter_map.

您还必须尝试从返回的 file_name() 创建一个 String,因为它不一定是 UTF-8.可以使用 mapand_then 的组合再次忽略(在本例中)具有非 UTF-8 名称的文件.

You'll also have to attempt to create a String from the returned file_name(), since it may not necessarily be UTF-8. Files with non-UTF-8 names can simply be ignored (in this example) again using a combination of map and and_then.

如果您让它忽略非Ok 目录条目和不是常规文件的路径(因此在 上返回None),它会是什么样子file_name()) 以及文件名不是 UTF-8 的文件:

Here's what it would look like if you make it ignore non-Ok directory entries and paths which aren't regular files (and thus return None on file_name()) as well as files whose file names are not UTF-8:

let paths = fs::read_dir(&Path::new(
  &env::current_dir().unwrap())).unwrap();

let names =
paths.filter_map(|entry| {
  entry.ok().and_then(|e|
    e.path().file_name()
    .and_then(|n| n.to_str().map(|s| String::from(s)))
  )
}).collect::<Vec<String>>();

playpen

如果你不是很熟悉 Rust 的函数式流程控制函数,例如mapand_then 等在 ResultOption 上,然后这是展开后的样子,忽略错误并且不进行错误处理.我把这留给你:

If you're not very familiar with Rust's functional flow-control functions, e.g. map, and_then, etc. on Result and Option, then here's what it would look like expanded out, without ignoring errors and without doing error handling. I leave that up to you:

let paths = fs::read_dir(&Path::new(
  &env::current_dir().unwrap())).unwrap();

let names =
paths.map(|entry| {
  let entry = entry.unwrap();

  let entry_path = entry.path();

  let file_name = entry_path.file_name().unwrap();

  let file_name_as_str = file_name.to_str().unwrap();

  let file_name_as_string = String::from(file_name_as_str);

  file_name_as_string
}).collect::<Vec<String>>();

playpen

这篇关于迭代 std::fs::ReadDir 并仅从路径中获取文件名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆