第二次读取文件句柄失败 [英] File handle failed to read second time

查看:52
本文介绍了第二次读取文件句柄失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 Perl 的 foreach 循环中第二次读取文件句柄?

How can I read from a file handle for the second time inside foreach loop in Perl?

foreach $a (@b){
    while(my $line = <IN>){
        if($line = /$a/){
            print $line;
        }
    }
}

上面的代码没有处理列表@b 中的第二个元素.如何使它成为可能?

The above code is not processing the second element from the list @b. How to make it possible?

推荐答案

你的内部循环,while(my $line = <IN>),从 IN 中提取行code> 处理,直到它到达文件末尾.

Your inner loop, while(my $line = <IN>), extracts lines from the IN handle until it reaches the end of the file.

当您的外循环 foreach $a (@b) 再次尝试从 IN 读取时,它仍处于文件末尾.foreach 循环的第一次迭代消耗了文件中的所有行,其他迭代什么也没留下.

When your outer loop, foreach $a (@b), tries to read from IN again, it's still at end-of-file. The first iteration of the foreach loop consumes all lines from the file, leaving nothing for the other iterations.

有几种可能的方法来解决这个问题:

There are several possible ways to fix this:

  • Seek back to the beginning of IN before you attempt to read from it again:

foreach $a (@b){
    seek IN, 0, 0
        or die "Cannot seek(): $!";
    while (my $line = <IN>) {
        ...
    }
}

但是,这仅适用于真实文件,不适用于管道、套接字或终端.

However, this only works for real files, not pipes or sockets or terminals.

预先将整个文件读入内存,然后迭代一个普通数组:

Read the whole file into memory up front, then iterate over a normal array:

my @lines = <IN>;
foreach $a (@b){
    foreach my $line (@lines) {
        ...
    }
}

但是,如果文件很大,这将使用大量内存.

However, if the file is big, this will use a lot of memory.

切换两个循环的顺序:

while (my $line = <IN>) {
    foreach $a (@b) {
        ...
    }
}

这是我的最爱.现在您只需要从文件中读取一次.@b 已在内存中,因此您可以根据需要对其进行多次迭代.

This is my favorite. Now you only need to read from the file once. @b is already in memory, so you can iterate over it as many times as you want.

附注:

  • 不要使用像 IN 这样的裸字文件句柄.普通变量(例如 $IN)在各方面都非常优越.
  • 不要使用名为 $a$b 的变量.它们有点特别,因为 Perl 在 sort.
  • 我个人的偏好是永远不要使用 <>.它奇怪地重载(它可能意味着 readlineglob,具体取决于您使用的确切语法)并且它不是非常直观.使用 readline 意味着永远不会有任何语法歧义,即使没有 Perl 经验的程序员也能弄清楚它的作用.
  • Don't use bareword filehandles like IN. Normal variables (such as $IN) are pretty much superior in every way.
  • Don't use variables called $a or $b. They're a bit special because Perl uses them in sort.
  • My personal preference is to never use < >. It's weirdly overloaded (it can mean either readline or glob, depending on the exact syntax you use) and it isn't terribly intuitive. Using readline means there's never any syntactic ambiguity and even programmers with no Perl experience can figure out what it does.

随着这些变化:

while (my $line = readline $IN) {
    foreach my $re (@regexes) {
        if ($line =~ /$re/) {
            print $line;
        }
    }
}

这篇关于第二次读取文件句柄失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆