我不明白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说所有的魔法都用于Drop
的{{1}}特征的实现,但现在似乎不是这样,因为我找不到File
特征实现Drop
或std::ops.rs
。
更新
我再次检查了std::old_io::fs.rs
File
的实现,发现write_all
方法适用于某些描述符(write
)。我没有在文档中找到任何关于它的相关信息,所以去了GitHub并找到了this。它看起来像我的问题的答案,但我对评论中的一行感到困惑:
//关闭stdio文件句柄毫无意义,所以永远不要这样做
这是什么意思?我自己永远不应该在我的fd上调用FileDesc
?或者他们自己不确定应该如何实施?
答案 0 :(得分:6)
对于POSIX平台,File
在mod struct File(FileDesc)
中定义为sys::fs2
,其中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()
。
答案 1 :(得分:0)
请参阅示例https://github.com/rust-lang/rust/blob/master/src/libstd/io/mod.rs#L112,其中指定了" drop guard"。
更新(对您的更新):stdio句柄是STDIN,STDOUT和STDERR,它们没有意义关闭(守护进程除外),所以在正常的IO操作期间不会这样做。 / p>