在Ruby中,重新分配IO流和使用IO#reopen
方法有什么区别?换句话说,
$stdout = newfile
和
$stdout.reopen(newfile)
答案 0 :(得分:3)
所以基本上重新打开会将$stdout
与newfile
stream =>联系起来$stdout
和newfile
将是与同一个流关联的两个文件实例。
=
实际上会将newfile
文件实例分配给$stdout
=> $stdout
和newfile
将是指向同一个File实例的两个变量。
后果:
使用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
答案 1 :(得分:0)
以前的IO被刷新并在后者(reopen
)的情况下关闭。
已添加:比较输出:
$stdout.write("Buffered")
$stdout = $stderr
$stdout.write("After assignment")
和
$stdout.write("Buffered")
$stdout.reopen($stderr)
$stdout.write("After reopen")
(比较的最佳方法是使用管道重定向输出)
答案 2 :(得分: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
只会影响当前的ruby进程。子进程将自己的标准输出写入文件描述符(FD)1,从FD 0读取标准输入,并将诊断输出写入FD 2.
如果您希望子进程继承更改,则需要重新打开该流,因为它会重用该文件描述符。请注意,只有在启动孩子之前reopen
,孩子才会受到影响。
一个用例:您正在编写一个守护程序脚本(或其他需要在您注销后继续运行的脚本)。最佳做法是将所有3个标准流重新打开到/dev/null
,否则如果脚本或子进程尝试使用流,则可能会出现损坏的管道。