2015-02-24 64 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

相關問題