【问题标题】:perl appending issuesperl 附加问题
【发布时间】:2011-05-04 21:06:36
【问题描述】:

我有一些代码附加到嵌套 for 循环中的一些文件中。退出 for 循环后,我想将 .end 附加到所有文件。

foreach my $file (@SPICE_FILES)
{
    open(FILE1, ">>$file") or die "[ERROR $0] cannot append to file : $file\n";
    print FILE1 "\n.end\n";
    close FILE1; 
}

我注意到在一些奇怪的情况下,“.end”被附加到文件的中间!

我该如何解决这个问题??

【问题讨论】:

  • 添加“.end”部分后,您确定没有写入另一个进程中的文件吗?正如您编写的代码一样,您所描述的绝对不应该发生。
  • 这对我来说非常好用。 @SPICE_FILES 的内容是唯一的吗?你写的不是“.end”吗?
  • 你在哪个平台上工作?
  • 考虑到下面的好答案,我想知道在尝试打印结束标记之前确保任何以前打开的文件句柄都被明确关闭是否可能无济于事。

标签: perl


【解决方案1】:

由于我还没有评论权限,所以我必须将其写为“答案”。

你使用任何不可靠的模块吗?

我遇到了一些问题,其中(显然)损坏的 perl 模块对输出缓冲做了一些事情。对我来说放置

$| = 1;

在代码中有帮助。上面的语句关闭 perls 输出缓冲(AFAIK)。它可能也有其他影响,但我没有看到任何负面影响。

【讨论】:

  • 输出缓冲的有趣之处
  • 是的,你是对的。 $| = 1 关闭缓冲,如果我没记错的话称为热文件句柄:)
【解决方案2】:

我猜你已经在一些以前打开的文件描述符中缓冲了数据。在重新打开之前尝试关闭它们:

open my $fd, ">>", $file or die "Can't open $file: $!"; 
print $fd, $data;
close $fd or die "Can't close: $!";

更好的是,您可以将这些文件句柄附加到数组/哈希中并在清理中写入它们:

push @handles, $fd;
# later
print $_ "\n.end\n" for @handles; 

这是一个重现中间“不可能”附加的案例:

 #!/usr/bin/perl -w
 use strict;

 my $file = "file";

 open my $fd, ">>", $file;
 print $fd "begin"; # no \n -- write buffered

 open my $fd2, ">>", $file;
 print $fd2 "\nend\n";
 close $fd2; # file flushed on close

 # program ends here -- $fd finally closed
 # you're left with "end\nbegin"

【讨论】:

  • 正如@Christopher 所说,您可以通过打开和关闭$| 轻松找出问题是否真的出在缓冲上。
  • 永远不要相信自动关闭,即使是在只读句柄上:它已经坏了,因为它不测试和报告错误。始终使用 close($fh) || die "Can't close: $!" 进行显式测试。
【解决方案3】:

不可能在文件中间附加一些东西。 O_APPEND 标志保证每个 write(2) 系统调用将其内容放在旧的 EOF 中,并通过增加您刚刚写入的字节数来更新 st_size 字段。

因此,如果您在查看时发现自己的数据最后没有显示出来,那么另一个代理随后向其写入了更多数据。

【讨论】:

    猜你喜欢
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 2011-11-26
    • 2014-08-16
    • 1970-01-01
    相关资源
    最近更新 更多