2015-02-24 61 views
2

我不明白当文件句柄超出范围时,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特征的实现中,但是现在看起来这不是真的,因为我在std::ops.rsstd::old_io::fs.rs中找不到Drop特征实现。

UPDATE

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

//关闭标准输入输出文件句柄是没有意义的,所以不要做

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

回答

5

对于POSIX平台,File定义为struct File(FileDesc)在mod 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()的析构函数。

+0

这似乎是有效的答案。谢谢 :) – mkrakhin 2015-02-24 13:04:04

0

参见例如https://github.com/rust-lang/rust/blob/master/src/libstd/io/mod.rs#L112,其规定了“下降后卫”。

更新(您更新):标准输入输出句柄STDIN,STDOUT和STDERR,这没有任何意义,关闭(除了daemonizing),所以这在正常的IO操作尚未完成。

+0

对不起,不明白它是如何与文件相关的。但它指出我再次检查Writer实现。我更新了一个问题。 – mkrakhin 2015-02-24 12:53:33

相关问题