2011-07-13 67 views

回答

3

所以基本上重新將同夥$stdoutnewfile stream =>$stdoutnewfile將是兩個與同一個流關聯的File實例。

=newfile File實例實際分配給$stdout =>$stdoutnewfile將指向同一個文件的實例兩個變量。

後果:

當使用reopen在實例中的任何改變(即不影響流本身)將不會被反映在其它實例。

=例子:

a = File.new('name') 
b = File.new('name') 

a.lineno #=> 0 
b.lineno #=> 0 

a.lineno = 3 

a.lineno #=> 3 
b.lineno #=> 0 

b = a 

a.lineno #=> 3 
b.lineno #=> 3 

a.lineno = 0 

a.lineno #=> 0 
b.lineno #=> 0 

reopen例如:

a = File.new('name') 
b = File.new('name') 

a.lineno #=> 0 
b.lineno #=> 0 

a.lineno = 3 

a.lineno #=> 3 
b.lineno #=> 0 

b.reopen(a) 

a.lineno #=> 3 
b.lineno #=> 3 

a.lineno = 0 

a.lineno #=> 0 
b.lineno #=> 3 
+0

作爲一個後續,'sync'選項如何處理這兩種流重定向方式? – jrdioko

+1

@jrdioko每次你通過'File'實例調用寫入方法時,'sync'就會寫入文件。 'reopen'和'='都會將'sync'值「複製」到目標'File'實例。要點:使用'='你將在兩個變量中處理相同的'File',所以每當你在兩者中任何一個寫入時都會更新流指針。使用'reopen'可以讓你在其中一個地方寫入,而不必修改其他人的位置,如果你寫入另一個地址,你最終將覆蓋以前的內容。 – robertodecurnex

0

上一頁IO刷新和關閉在後者(reopen)的情況下,我相信。

補充:比較輸出:

$stdout.write("Buffered") 
$stdout = $stderr 
$stdout.write("After assignment") 

$stdout.write("Buffered") 
$stdout.reopen($stderr) 
$stdout.write("After reopen") 

(最好的方式來比較是通過使用重定向輸出管道)

0

,當你正在運行的子進程的差異是很重要的。

分配:

$stdout = File.open("/dev/null", "w") 
system "ls" 
warn $stdout.fileno # file descriptor number 

輸出 - 注意如何system的輸出還出現了:

1.txt 2.txt 
7 

重啓:

$stdout.reopen("/dev/null") 
system "ls" 
warn $stdout.fileno 

輸出 - 日Èsystem輸出被送到/dev/null

1 

總結:

$stdout$stdin,或重新分配$stderr隻影響當前紅寶石過程。子進程會將自己的標準輸出寫入文件描述符(FD)1,從FD 0讀取標準輸入,並將診斷輸出寫入FD 2.

如果您希望孩子繼承更改,則需要重新打開該流,因爲它重用了文件描述符。請注意,如果您在啓動孩子之前reopen之前,孩子只會受到影響。

一個用例:您正在編寫一個守護進程腳本(或者其他腳本,在您註銷後需要繼續運行)。最佳做法是將所有3個標準流重新打開到/dev/null,否則如果腳本或子進程嘗試使用流,則可能會損壞管道。

相關問題