当文件超出范围时,文件句柄如何关闭?

mkr*_*hin 3 io rust

我不明白Rust在超出范围时对文件句柄的作用.例如,我创建一个文件并在其中写入几个单词:

let wd = os::getcwd().unwrap_or(Path::new("/"));
let mut file = File::create(&Path::new("daemon_log.txt"));
file.write_all(format!("DAEMON CWD: {}", wd.as_str().unwrap_or("some problems")).as_bytes());
Run Code Online (Sandbox Code Playgroud)

在文件超出范围时,编译器应插入释放内存的指令.如果我对通常实现阻塞IO的理解是正确的,那么除了释放内存之外,该进程还应该释放一些锁.

我担心的是,在源代码中File,我找不到编译器的任何提示.这老文章说,所有的魔法进入实施的Drop特点为File,但似乎这不是真的,现在,因为我无法找到Drop在任何特质的实施std::ops.rs也不在std::old_io::fs.rs.

UPDATE

我再次检查了Files的实现,write_all发现该write方法适用于一些descriptor(FileDesc).我没有在docs中找到任何关于它的相关信息,所以去了GitHub并找到了这个.它看起来像我的问题的答案,但我对评论中的一行感到困惑:

//关闭stdio文件句柄毫无意义,所以永远不要这样做

这是什么意思?我libc::close自己永远不应该对自己的fd进行调用?或者他们自己不确定应该如何实施?

ham*_*ene 6

对于POSIX平台,File定义为struct File(FileDesc)mod sys::fs2,其中FileDesc是文件描述符编号的包装.该的析构函数FileDesc关闭文件:

impl Drop for FileDesc {
    fn drop(&mut self) {
        // closing stdio file handles makes no sense, so never do it. Also, note
        // that errors are ignored when closing a file descriptor. The reason
        // for this is that if an error occurs we don't actually know if the
        // file descriptor was closed or not, and if we retried (for something
        // like EINTR), we might close another valid file descriptor (opened
        // after we closed ours.
        if self.fd > libc::STDERR_FILENO {
            let _ = unsafe { libc::close(self.fd) };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Windows平台的实现定义FileHandlevalue的包装器,析构函数的调用CloseHandle().