在Ruby中,重新分配IO流並使用IO#reopen
方法有什麼區別?換句話說,就是重新分配和重新打開Ruby IO流之間的區別
$stdout = newfile
之間的區別:
$stdout.reopen(newfile)
在Ruby中,重新分配IO流並使用IO#reopen
方法有什麼區別?換句話說,就是重新分配和重新打開Ruby IO流之間的區別
$stdout = newfile
之間的區別:
$stdout.reopen(newfile)
所以基本上重新將同夥$stdout
與newfile
stream =>$stdout
和newfile
將是兩個與同一個流關聯的File實例。
=
將newfile
File實例實際分配給$stdout
=>$stdout
和newfile
將指向同一個文件的實例兩個變量。
後果:
當使用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
上一頁IO刷新和關閉在後者(reopen
)的情況下,我相信。
補充:比較輸出:
$stdout.write("Buffered")
$stdout = $stderr
$stdout.write("After assignment")
和
$stdout.write("Buffered")
$stdout.reopen($stderr)
$stdout.write("After reopen")
(最好的方式來比較是通過使用重定向輸出管道)
,當你正在運行的子進程的差異是很重要的。
分配:
$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
,否則如果腳本或子進程嘗試使用流,則可能會損壞管道。
作爲一個後續,'sync'選項如何處理這兩種流重定向方式? – jrdioko
@jrdioko每次你通過'File'實例調用寫入方法時,'sync'就會寫入文件。 'reopen'和'='都會將'sync'值「複製」到目標'File'實例。要點:使用'='你將在兩個變量中處理相同的'File',所以每當你在兩者中任何一個寫入時都會更新流指針。使用'reopen'可以讓你在其中一個地方寫入,而不必修改其他人的位置,如果你寫入另一個地址,你最終將覆蓋以前的內容。 – robertodecurnex