在Perl中从大文件中读取特定行
有没有一种快速高效的方法可以读取大文件的特定行,而无需将其加载到内存中 我编写了一个perl脚本,它运行许多fork,我希望它们从文件中读取特定的行 目前,我正在使用外部命令:在Perl中从大文件中读取特定行,perl,file,line,Perl,File,Line,有没有一种快速高效的方法可以读取大文件的特定行,而无需将其加载到内存中 我编写了一个perl脚本,它运行许多fork,我希望它们从文件中读取特定的行 目前,我正在使用外部命令: sub getFileLine { my ( $filePath, $lineWanted ) = @_; $SIG{PIPE} = '_IGNORE_'; open( my $fh, '-|:utf8', "tail -q -n +$lineWanted \"$filePath\" | head
sub getFileLine {
my ( $filePath, $lineWanted ) = @_;
$SIG{PIPE} = '_IGNORE_';
open( my $fh, '-|:utf8', "tail -q -n +$lineWanted \"$filePath\" | head -n 1" );
my $line = <$fh>;
close $fh;
chomp( $line );
return $line;
}
子getFileLine{
my($filePath,$lineWanted)=@;
$SIG{PIPE}=''u忽略'';
打开(我的$fh,,-:utf8',“tail-q-n+$lineWanted\”$filePath\“| head-n1”);
我的$line=;
收盘价$fh;
chomp($line);
返回$line;
}
它的速度很快,而且可以工作——但是也许有一种更“Perl风格”的方法,和这个方法一样快,内存效率也一样高
正如您所知,在Perl中创建fork进程会复制主进程内存——因此,如果主进程使用10MB,fork将至少使用那么多内存
我的目标是尽可能降低fork进程(所以在运行forks之前,主进程也是如此)的内存使用。这就是为什么我不想将整个文件加载到内存中。在继续之前,了解
fork
的工作原理非常重要。当您fork
一个进程时,操作系统使用语义来共享父进程和子进程的大部分内存;只有父级和子级之间不同的内存量需要单独分配
要在Perl中读取一行文件,有一种简单的方法:
open my $fh, '<', $filePath or die "$filePath: $!";
my $line;
while( <$fh> ) {
if( $. == $lineWanted ) {
$line = $_;
last;
}
}
打开我的$fh,看看核心模块 你不需要用叉子。可以想象,从文件中读取特定行是一种非常常见的操作,CPAN上的20k模块之一已经在执行该操作了
内存效率高且速度快。顺便说一句,它是忽略,而不是\u忽略
。我认为Tie::File
内存效率低。OP不是要求低内存使用率吗?@Zaid它实际上是合理的内存效率;它不会将文件的全部内容存储在内存中,只存储每行的偏移量列表。它不是免费的(即使只是保留每个偏移量的标量,每行也会占用一些空间),但它通常足以轻松处理数百兆字节的文件。@hobbs:Yup。从那时起,我就查看了文档(注释现在已经很旧了),它清楚地表明它不是一个内存占用器。