【问题标题】:Refreshing line reading operator Perl刷新行读运算符 Perl
【发布时间】:2010-11-23 22:58:28
【问题描述】:

在 perl 中使用 运算符达到 eof 后会发生什么?

我正在逐行阅读INP1

while(<INP1>) {
}

但我需要多次读取,并且每次都需要从文件的开头开始。我怎样才能做到这一点?有没有类似在 perl 中刷新流的东西?

提前致谢。

【问题讨论】:

    标签: perl file-io filestream


    【解决方案1】:

    如果INP1 连接到常规文件句柄(不是套接字句柄或管道句柄),您也可以seek 回到文件开头。

    while(<INP1>) {
       ...
    }
    seek INP1, 0, 0;
    
    # do it again
    while (<INP1>) {
       ...
    }
    

    另一种选择是将整个文件加载到一个数组中,然后根据需要循环遍历该数组。如果整个文件可以在内存中舒适地放置,并且文件的内容不会在遍历之间发生变化,那么这是一个好主意。

    open INP1, '<', $the_file;
    @INP1 = <INP1>;
    close INP1;
    
    foreach (@INP1) {
       ...
    }
    
    # do it again
    foreach (@INP1) {
       ...
    }
    

    【讨论】:

    • 使用词法范围的文件句柄
    【解决方案2】:

    除了使用seek 回到文件开头,您还可以使用Tie::File 将文件视为行数组。根据您的访问模式,这可能比每次从头开始重新读取文件更有效。

    【讨论】:

      【解决方案3】:

      你可以seek回到开头:

      use Fcntl;
      open INP1, ...
      while (<INP1>) {
      }
      seek INP1, 0, SEEK_SET;
      while (<INP1>) {
      }
      

      只有当 INP1 是一个真实文件(不是管道或套接字)时,这才能正常工作。

      【讨论】:

      • 我当然希望这个程序以use strictuse warnings qw&lt;FATAL all&gt;use autodieuse open qw&lt; :std IO :utf8 &gt;END{close STDOUT} 和明确的close INP1 开头。比如,你知道吗? :(
      • @tchrist:很好的建议,但他们没有解决 OP 提出的问题,所以我认为它们离题,不会将它们包含在我的答案中。
      • @Adrian:在什么情况下可以接受不检查其成功的系统调用?
      • @tchrist => 我认为问题的一部分可能是大多数 perldocs 从未明确检查错误,这可能会尽可能地阻止错误。我刚刚花了一分钟谷歌搜索文档,我看到的唯一一个带有错误检查的 seek 例子是在你的一个教程中:)
      • @Eric:同意,但我不相信这是件坏事。提供例子来说明一个观点;错误检查会让人分心。如果一个例子是关于使用文件句柄的,open 的任何外观都是次要的;错误检查是三次噪声。此外,适当的错误响应取决于应用程序,因此货物错误检查也不正确(尽管平均而言它可能会导致更好的代码)。最后,“最佳实践”发生了变化。例如即使文档有open or die,也有人希望将其更改为use autodie
      猜你喜欢
      • 2017-02-07
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多