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

How is a file handle closed when it goes out of scope?

我不明白 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());

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

我担心的是,在 File 的源代码中,我找不到编译器执行此操作的任何提示。 This old article 说所有魔法都用于 FileDrop 特性的实现,但现在看来这不是真的,因为我找不到 Drop 特性的实现std::ops.rsstd::old_io::fs.rs.

更新

我再次检查了 Filewrite_all 的实现,发现 write 方法适用于某些描述符 (FileDesc)。我没有在文档中找到关于它的任何相关信息,所以去 GitHub 找到了 this。它看起来像是我问题的答案,但我对评论中的一行感到困惑:

// closing stdio file handles makes no sense, so never do it

这是什么意思?我不应该自己在我的 fd 上调用 libc::close 吗?或者他们自己也不确定应该如何实施?

参见示例 https://github.com/rust-lang/rust/blob/master/src/libstd/io/mod.rs#L112,它指定了 "drop guard"。

Update(对您的更新):stdio 句柄是 STDIN、STDOUT 和 STDERR,关闭它们没有任何意义(守护进程除外),因此在正常的IO操作。

对于 POSIX 平台,File 在 mod sys::fs2 中定义为 struct File(FileDesc),其中 FileDesc 是文件描述符的包装器数字。 destructor of 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) };
        }
    }
}

Windows 平台的实现将 File 定义为 Handle 值的包装器,calls CloseHandle().

的析构函数