【问题标题】:How can I read, analyze, and then "un-read" and reread the beginning of an input stream in Perl?如何在 Perl 中读取、分析、然后“取消读取”并重新读取输入流的开头?
【发布时间】:2010-10-30 17:24:36
【问题描述】:

我正在读取和处理来自 Perl 中的 ARGV 文件句柄(即 while(<>) 构造)的输入流,这是一个常规文件句柄,可能是 STDIN。但是,我需要分析输入的重要部分,以便检测它以四种不同但极其相似的格式中的哪一种进行编码(FASTQ 质量分数的不同 ASCII 编码;请参阅here)。一旦我确定了数据的格式,我需要返回并再次解析这些行以实际读取数据。

所以我需要读取流的前 500 行左右两次。或者,换个角度来看,我需要阅读前 500 行,然后将它们“放回去”,这样我才能再次阅读它们。由于我可能正在阅读 STDIN,因此我不能只是回到开头。而且文件很大,所以我不能将所有内容都读入内存(尽管将前 500 行读入内存是可以的)。最好的方法是什么?

或者,我可以以某种方式复制输入流吗?

编辑:等一下。我刚刚意识到我不能再将输入作为一个大流处理,因为我必须独立检测每个文件的格式。所以我不能使用 ARGV。不过,剩下的问题仍然存在。

【问题讨论】:

    标签: perl stdin duplication


    【解决方案1】:

    如你所说,如果文件句柄可能是 STDIN,你不能使用seek 来回退它。但这仍然很简单。我不会打扰模块:

    my @lines;
    
    while (<$file>) {
      push @lines, $_;
      last if @lines == 500;
    }
    
    ... # examine @lines to determine format
    
    while (defined( $_ = @lines ? shift @lines : <$file> )) {
      ... # process line
    }
    

    请记住,在这种情况下您需要一个显式的 defined,因为将隐式 defined 添加到某些 while 循环的特殊情况不适用于这个更复杂的表达式。

    【讨论】:

      【解决方案2】:

      一个CPAN module,它为IO::Handle 类提供了一个unread 方法。然而,它的警告让人有些谨慎。我会仔细评估它的适用性。

      如果您真的只需要节省 500 行,每行都相当短,那么该模块可能就足够了;它的例子确实使用了STDIN

      但是,我对魔法 ARGV 感到紧张。如果您的&lt;&gt; 运算符导致打开和读取多个不同的文件,那么我不知道您是否能够备份到与当前打开的文件不同的文件。

      因此,您最终可能只是自己编写推回逻辑。要么这样,要么对与多个输入文件和/或STDIN 的性质相关的 ARGV 处理施加某种限制。

      我的大多数带有魔法 ARGV 处理的程序在开始时都有防护,内容如下:

      if (@ARGV == 0 && -t STDIN) {
          # select one or the other of the next two lines:
      
          # opt 1: emit warning 
          warn "$0: reading stdin from /dev/tty\n";
      
          # opt 2: populate @ARGV
          @ARGV = grep { -f && -T } <*>;  # glob plain textfiles
      
       }
      

      在上面的第二种情况下,它默认为当前目录中的所有纯文本文件,如果grep 产生空列表,人们还应该决定该怎么做。

      对于一些期望或至少承认目录参数的程序,我偶尔会将空的@ARGV 初始化为".",以便程序默认为进程的当前工作目录。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-22
        • 1970-01-01
        • 2023-04-04
        • 2014-09-02
        • 2012-04-09
        • 2013-02-15
        • 1970-01-01
        相关资源
        最近更新 更多