创建临时目录项,在读取DirEntry路径时仍在使用时会被释放。

huangapple go评论73阅读模式
英文:

creates temporary which is freed while still in use when reading path of DirEntry

问题

I'm trying to read all files in a folder, as simple as that. And then filter for mp4 extensions. But I get following error:

创建临时目录项,在读取DirEntry路径时仍在使用时会被释放。

I don't understand, how in the following code, the e.path statement could "create a temporary". (The whole code is obviously in them same "Ok" closure.). Is there some special stuff happening in the path() method? I could not find anything strange in the documentation.

let paths = fs::read_dir(&folder).unwrap();

for path in paths {
    match path {
        Ok(e) => {
            let fullPath = e.path();
            let extension = e
                .path()
                .extension()
                .expect("Error getting extension")
                .to_str()
                .expect("Could not convert extensions to string");
            println!("{}", extension)
        }

        _ => {}
    }
}

I tried numerous things and stuff like .path().metadata() does not throw this error. Only when in combination with extension() this seems to be happening? It's really confusing me, how a task this simple becomes so complex.

英文:

I'm trying to read all files in a folder, as simple as that. And then filter for mp4 extensions. But I get following error:

创建临时目录项,在读取DirEntry路径时仍在使用时会被释放。

I don't understand, how in the following code, the e.path statement could "create a temporary". (The whole code is obviously in them same "Ok" closure.). Is there some special stuff happening in the path() method? I could not find anything strange in the documentation.

let paths = fs::read_dir(&folder).unwrap();

for path in paths {
    match path {
        Ok(e) => {
            let fullPath = e.path();
            let extension = e
                .path()
                .extension()
                .expect("Error getting extension")
                .to_str()
                .expect("Could not convert extensions to string");
            println!("{}", extension)
        }

        _ => {}
    }

I tried numerous things and stuff like .path().metadata() does not throw this error. Only when in combination with extension() this seems to be happening? It's really confusing me, how a task this simple becomes so complex.

答案1

得分: 1

DirEntry::path() 返回一个 PathBufPathBuf::extension() 返回一个 Option<&amp;OsStr>。正如你所见,OsStr 是从原始的 PathBuf / Path 中借用的。问题是,你试图将扩展名绑定到一个变量,但你没有分配从中借用的 PathBuf 给一个变量。

因此编译器正确地指出 PathBuf 是临时的,并且会在 let extension = ... 语句之后被丢弃,因此 extension 不能继续指向它。

你已经做对了 - 将那个 PathBuf 的另一个副本赋值给 fullPath。所以你可以直接从中借用扩展名。

这里是一个完全独立的解决方案:

use std::fs;

fn main() {
    let folder = "./src";
    let paths = fs::read_dir(&amp;folder).unwrap();

    for path in paths {
        if let Ok(e) = path {
            let full_path = e.path(); // 这将至少存活和 `extension` 一样长的时间,所以从中借用是可以的。
            let extension = full_path
                .extension()
                .expect("获取扩展名时出错")
                .to_str()
                .expect("无法将扩展名转换为字符串");
            println!("{}", extension)
        }
    }
}
英文:

DirEntry::path() returns a PathBuf, and PathBuf::extension() returns an Option&lt;&amp;OsStr&gt;. As you can see, the OsStr is borrowed from the original PathBuf / Path. The problem is, you're trying to bind the extension to a variable, but you do not assign the PathBuf that is borrowed from to a variable as well.

So the compiler is correct in saying that the PathBuf is temporary, and will be dropped after your let extension = ... statement, and thus extension can not keep pointing to it.

You're already doing the right thing - assigning another copy of that PathBuf to fullPath. So you can just borrow the extension from it.

Here's a fully self-contained solution:

use std::fs;

fn main() {
    let folder = &quot;./src&quot;;
    let paths = fs::read_dir(&amp;folder).unwrap();

    for path in paths {
        if let Ok(e) = path {
            let full_path = e.path(); // This will live at least as long as `extension`, so
                                      // borrowing from it is fine.
            let extension = full_path
                .extension()
                .expect(&quot;Error getting extension&quot;)
                .to_str()
                .expect(&quot;Could not convert extensions to string&quot;);
            println!(&quot;{}&quot;, extension)
        }
    }
}

huangapple
  • 本文由 发表于 2023年5月7日 21:00:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76194095.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定