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

时间:2015-02-24 12:17:52

标签: 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());

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

我担心的是,在File的源代码中,我找不到编译器的任何提示。 This old article说所有的魔法都用于Drop的{​​{1}}特征的实现,但现在似乎不是这样,因为我找不到File特征实现Dropstd::ops.rs

更新

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

  

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

这是什么意思?我自己永远不应该在我的fd上调用FileDesc?或者他们自己不确定应该如何实施?

2 个答案:

答案 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>