在Perl中解析巨大的文本文件

时间:2013-01-24 20:29:12

标签: perl parsing

我的基因组文件类似于下面的30 gb,

>2RHet assembled 2006-03-27 md5sum:88c0ac39ebe4d9ef5a8f58cd746c9810
GAGAGGTGTGGAGAGGAGAGGAGAGGAGTGGTGAGGAGAGGAGAGGTGAG
GAGAGGAGAGGAGAGGAGAGGAATGGAGAGGAGAGGAGTCGAGAGGAGAG
GAGAGGAGTGGTGAGGAGAGGAGAGGAGTGGAGAGGAGACGTGAGGAGTG
GAGAGGAGAGTAGTGGAGAGGAGTGGAGAGGAGAGGAGAGGAGAGGACGG
ATTGTGTTGAGGACGGATTGTGTTACACTGATCGATGGCCGAGAACGAAC

我正在尝试解析文件并快速完成任务, 按字符使用下面的代码字符 但角色没有打印

open (FH,"<:raw",'genome.txt') or die "cant open the file $!\n";

until ( eof(FH) ) {

$ch = getc(FH);
print "$ch\n";# not printing ch

}
close FH;

1 个答案:

答案 0 :(得分:3)

你的错误是遗忘eof

until (eof FH) { ... }

非常不太可能是最有效的解决方案:Perl比C更慢,所以我们希望尽可能少的循环迭代,并且在perl内部中完成的工作量也是如此。我们可以得到。这意味着逐个字符地读取文件是

另外,使用词法变量(用my声明)而不是全局变量;这可能会导致性能提升。

选择自然记录分隔符(如\n),或读取一定数量的字节:

local $/ = \256; # read 256 bytes at a time.
while (<FH>) {
  # do something with the bytes
}

(见perlvar

您还可以摆脱openreadline甚至getc为您做的所有奢侈品,并使用sysopensysread进行全面控制。然而,这种方式就是疯狂。

# not tested; I will *not* use sysread.
use Fcntl;
use constant NUM_OF_CHARS => 1; # equivalent to getc; set higher maybe.
sysopen FH, "genome.txt", O_RDONLY or die;

my $char;
while (sysread FH, $char, NUM_OF_CHARS, 0) {
  print($char .= "\n");  # appending should be better than concatenation.
}

如果我们走得那么远,使用Inline::C只是一个很小的,可能更可取的步骤。