我想从<>中读取100 KB,对其进行一些测试,然后将100 KB恢复,这样它们将被<>读取后面。
在元代码中:
$data100kb = read(<>,100000);
testing($data100kb);
unget(<>,$data100kb);
while(<>) {
do stuff;
}
我事先并不知道&lt;&gt;将为我提供实际文件,管道或实际文件的串联。所以它应该适用于:
cat bigfile_a bigfile_b | perl my_program
假设bigfiles是1000 * RAM大小,因此复制输入非常昂贵。
如果我只能从STDIN读取,那是可以接受的。
背景
第一个100kb告诉我如何解析完整输入,但解析器也需要这个输入。
答案 0 :(得分:1)
这似乎适用于STDIN。如果可以更快地完成它将会很棒。
read(STDIN, $first, 100000);
unget($first);
compute($first);
while($_=get_line()) {
# Similar to while(<>)
}
my @line_cache;
sub get_line {
if(@line_cache) {
my $line = shift @line_cache;
if(@line_cache) {
# not last line
return $line;
} else {
# last line - may be incomplete
if(substr($line, -1, 1) eq $/) {
# Line is complete
return $line;
} else {
return $line. scalar(<STDIN>);
}
}
} else {
return scalar(<STDIN>);
}
}
sub unget {
for(@_) {
# Split into lines
push @line_cache, split m:(?<=$/):;
}
}
答案 1 :(得分:1)
为后代...我写了FileHandle :: Unget解决这个问题。
答案 2 :(得分:0)
我不知道这是否满足您的需要。如果您坚持使用&lt;&gt ;,那么我猜您必须使用tie
。
#copy STDIN to another filehandle: $fh
my $fakefile = join '', <STDIN>;
open my $fh, '<', \$fakefile;
#read 100kb
read $fh, my $data100kb, 100_000;
#do something with the data
#$data100kb =~ y/a/b/;
#print $data100kb;
#reset $fh
seek $fh, 0, 0;
while(<$fh>){
print;# do some stuff
}