- 论坛徽章:
- 0
|
接上一个帖子:
File::BufferedREader.pm
package File::BufferedReader ;
use strict;
use Symbol;
use Fcntl qw( :seek O_RDONLY ) ;
use Carp ;
my $max_read_size = 1 << 14 ;
my $default_rec_sep ;
BEGIN {
if ( $^O =~ /win32/i || $^O =~ /vms/i ) {
$default_rec_sep = "\015\012" ;
}elsif ( $^O =~ /mac/i ) {
$default_rec_sep = "\015" ;
}else {
$default_rec_sep = "\012" ;
}
}
sub new{
my($class,$filename,$rec_sep,$sep_is_regex) = @_;
defined( $filename ) || return ;
$rec_sep ||= $default_rec_sep ;
my $is_crlf = $rec_sep eq "\015\012" ;
my $handle = gensym;
sysopen( $handle, $filename, O_RDONLY ) || return ;
binmode $handle ;
my $self = bless{
'file_name' => $filename,
'handle' => $handle,
'seek_pos' => 0,
'lines' => [],
'is_crlf' => $is_crlf,
'rec_sep' => $rec_sep,
'sep_is_regex' => $sep_is_regex,
'is_last' =>0
}, $class;
return ($self);
}
sub readline{
my ($self) = @_;
my $read_buf ;
my $lines_ref = $self->{'lines'};
return unless $lines_ref;
while(1){
if(@{$lines_ref}>1){
$lines_ref->[0] =~s/\015\012/\n/
if $self->{'is_crlf'} ;
return (shift @{$lines_ref});
}
my $is_last = $self->{'is_last'};
if($is_last == 1){
$lines_ref->[0] =~s/\015\012/\n/
if $self->{'is_crlf'} ;
return (shift @{$lines_ref});
}
my $handle = $self->{'handle'};
my $seek_pos = $self->{'seek_pos'};
sysseek($handle,$seek_pos,SEEK_SET);
my $read_cnt = sysread($handle,$read_buf,$max_read_size);
$self->{'seek_pos'}+=$read_cnt;
$self->{'is_last'}=1 if ($read_cnt<$max_read_size);
my $text = shift @{$lines_ref} if @{$lines_ref} ;
$text .= $read_buf;
@{$lines_ref} = ( $self->{'sep_is_regex'} ) ?
$text =~ /(.*?$self->{'rec_sep'}|.+)/gs :
$text =~ /(.*?\Q$self->{'rec_sep'}\E|.+)/gs ;
}
}
sub eof {
my ($self) = @_;
my $lines_count = @{$self->{'lines'}};
my $is_last = $self->{'is_last'};
return($is_last == 1 && $lines_count ==0);
}
sub close {
my ( $self ) = @_ ;
my $handle = delete( $self->{'handle'} ) ;
delete( $self->{'lines'} ) ;
CORE::close( $handle ) ;
} |
测试结果:
对1,000,000的测试
<>操作的17s
采用BufferedReader并设置缓冲区大小为8k,花了13s,缓冲区为16k,花15s
对10,000,000的测试
<>操作169s
采用BufferedReader并设置缓冲区大小为8k,花了132s,缓冲区为16k,花251s
本人机器配置,内存2G,cpu Core2 Duo E4600(2.4GH)
有什么好的别的方法,忘高手指教!!! |
|