检查文件是否属于给定类型
Check if a file is of a given type
如何修复此功能?我认为我必须将名称转换为 String
,但随后我必须将其转换回 str
才能使用 ends_with
。我应该使用另一个函数来做到这一点吗?
use walkdir::{DirEntry};
fn is_filetype(entry: &DirEntry, _type: &str) -> bool {
entry.file_name()
.to_str()
.to_lowercase()
.map(|s| s.ends_with(_type))
.unwrap_or(false)
}
error[E0599]: no method named `to_lowercase` found for enum `Option` in the current scope
--> src/bin/parse_torrent.rs:45:10
|
45 | .to_lowercase()
| ^^^^^^^^^^^^ method not found in `Option<&str>`
修复问题中提供的代码的最简单方法可能是使用 map_or
,就像@ChayimFriedman 在评论中建议的那样。
fn is_filetype(entry: &DirEntry, _type: &str) -> bool {
entry
.file_name()
.to_str()
.map_or(false, |s| s.to_lowercase().ends_with(_type))
}
但是,如果我们扩展它以查看其他方法,则还有更多选择。
过去,我使用的一种方法是使用内置的 .extension()
方法。
if path.extension().and_then(OsStr::to_str) == Some("txt") {
do_the_thing();
}
不过,我们或许可以做得更好。经过一番修改后,这就是我的想法。
pub trait FileExtension {
fn has_extension<S: AsRef<str>>(&self, extensions: &[S]) -> bool;
}
impl<P: AsRef<Path>> FileExtension for P {
fn has_extension<S: AsRef<str>>(&self, extensions: &[S]) -> bool {
if let Some(ref extension) = self.as_ref().extension().and_then(OsStr::to_str) {
return extensions
.iter()
.any(|x| x.as_ref().eq_ignore_ascii_case(extension));
}
false
}
}
这个新版本为我们提供了一些额外的功能。我们可以检查多种扩展类型,这让我们可以更灵活地选择它使用的类型。
// original
if is_filetype(&dir_entry, "txt") {}
// Alternate
if dir_entry.path().has_extension(&["txt"]) {}
// We can also check for multiple extensions
if dir_entry.path().has_extension(&["png", "jpg", "jpeg", "gif", "bmp"]) {}
也就是说,有一些 pros/cons:
- 扩展名为
.tar.gz
的文件将被读取为扩展名为 gz
。
- 名称以句点开头的文件不会被误读为扩展名(例如:文件夹
~/.ssh
被正确识别为没有扩展名)。
- 文件开头的“魔术字节”不会在需要时检查文件类型。
如何修复此功能?我认为我必须将名称转换为 String
,但随后我必须将其转换回 str
才能使用 ends_with
。我应该使用另一个函数来做到这一点吗?
use walkdir::{DirEntry};
fn is_filetype(entry: &DirEntry, _type: &str) -> bool {
entry.file_name()
.to_str()
.to_lowercase()
.map(|s| s.ends_with(_type))
.unwrap_or(false)
}
error[E0599]: no method named `to_lowercase` found for enum `Option` in the current scope
--> src/bin/parse_torrent.rs:45:10
|
45 | .to_lowercase()
| ^^^^^^^^^^^^ method not found in `Option<&str>`
修复问题中提供的代码的最简单方法可能是使用 map_or
,就像@ChayimFriedman 在评论中建议的那样。
fn is_filetype(entry: &DirEntry, _type: &str) -> bool {
entry
.file_name()
.to_str()
.map_or(false, |s| s.to_lowercase().ends_with(_type))
}
但是,如果我们扩展它以查看其他方法,则还有更多选择。
过去,我使用的一种方法是使用内置的 .extension()
方法。
if path.extension().and_then(OsStr::to_str) == Some("txt") {
do_the_thing();
}
不过,我们或许可以做得更好。经过一番修改后,这就是我的想法。
pub trait FileExtension {
fn has_extension<S: AsRef<str>>(&self, extensions: &[S]) -> bool;
}
impl<P: AsRef<Path>> FileExtension for P {
fn has_extension<S: AsRef<str>>(&self, extensions: &[S]) -> bool {
if let Some(ref extension) = self.as_ref().extension().and_then(OsStr::to_str) {
return extensions
.iter()
.any(|x| x.as_ref().eq_ignore_ascii_case(extension));
}
false
}
}
这个新版本为我们提供了一些额外的功能。我们可以检查多种扩展类型,这让我们可以更灵活地选择它使用的类型。
// original
if is_filetype(&dir_entry, "txt") {}
// Alternate
if dir_entry.path().has_extension(&["txt"]) {}
// We can also check for multiple extensions
if dir_entry.path().has_extension(&["png", "jpg", "jpeg", "gif", "bmp"]) {}
也就是说,有一些 pros/cons:
- 扩展名为
.tar.gz
的文件将被读取为扩展名为gz
。 - 名称以句点开头的文件不会被误读为扩展名(例如:文件夹
~/.ssh
被正确识别为没有扩展名)。 - 文件开头的“魔术字节”不会在需要时检查文件类型。