Perl - 无法刷新STDOUT或STDERR

时间:2013-06-24 16:31:11

标签: perl

Perl 5.14现货Ubuntu Precise回购。尝试编写一个简单的包装器来监视从一个流复制到另一个流的进度:

use IO::Handle;
while ($bufsize = read (SOURCE, $buffer, 1048576)) {
    STDERR->printflush ("Transferred $xferred of $sendsize bytes\n");
    $xferred += $bufsize;
    print TARGET $buffer;
}

这不会按预期执行(每次读取1M缓冲区时写一行)。我最终看到了第一行(空白值为$ xferred),然后在第7行和第8行(8MB传输)上的所有内容都没有任何内容。几个小时以来我的脑子都在敲打 - 我读过perldocs,我读过经典的“遭受缓冲”的文章,我尝试了从select和$ | ++到IO :: Handle到binmode的所有内容( STDERR,“:: unix”)给你起名。我也尝试使用IO :: Handle(TARGET-> flush)在每一行中刷新TARGET。没有骰子。

还有其他人遇到过这个吗?我没有任何想法。睡一秒钟“修复”了问题,但显然我每次读取缓冲区时都不想睡一秒,这样我的进度就会在屏幕上输出!

FWIW,无论是输出到STDERR还是STDOUT,问题都完全相同。

1 个答案:

答案 0 :(得分:5)

Perl read来电fread(3),而非read(2)

这意味着它通过libc并且可能使用比您大的内部缓冲区;即,它获取所有要接收的数据,然后以1MB的增量快速向您发送数据。

如果此猜想正确,则解决方案可能使用sysread,而read(2)代替read