重新分配和重新打开Ruby IO流之间的区别

时间:2011-07-13 17:54:14

标签: ruby io stdout variable-assignment

在Ruby中,重新分配IO流和使用IO#reopen方法有什么区别?换句话说,

之间有什么区别
$stdout = newfile

$stdout.reopen(newfile)

3 个答案:

答案 0 :(得分:3)

所以基本上重新打开会将$stdoutnewfile stream =>联系起来$stdoutnewfile将是与同一个流关联的两个文件实例。

=实际上会将newfile文件实例分配给$stdout => $stdoutnewfile将是指向同一个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,否则如果脚本或子进程尝试使用流,则可能会出现损坏的管道。