File-Sip
view release on metacpan or search on metacpan
lib/File/Sip.pm view on Meta::CPAN
package File::Sip;
#ABSTRACT: file parser intended for big files that don't fit into main memory.
use Moo;
use Carp 'croak';
use IO::File;
use Encode qw(decode);
use feature ':5.10';
has path => (
is => 'ro',
required => 1,
);
has line_separator => (
is => 'ro',
default => sub {qw/(\015\012|\015|\012)/},
);
has is_utf8 => (
is => 'ro',
default => sub {1},
);
# internal cursor for iterations
has _read_line_position => (
is => 'rw',
default => sub {0},
);
sub read_line {
my ( $self, $line_number ) = @_;
$line_number //= $self->_read_line_position;
my $fh = $self->_fh;
my $line_index = $self->index->[$line_number];
return if !defined $line_index;
my $previous_line_index =
( $line_number == 0 ) ? 0 : $self->index->[ $line_number - 1 ];
my $line;
seek( $fh, $previous_line_index, 0 );
read( $fh, $line, $line_index - $previous_line_index );
$self->_read_line_position( $line_number + 1 ) if @_ == 1;
return decode( "utf8", $line ) if defined $line && $self->is_utf8;
return $line;
}
# file handle return by IO::File
has _fh => (
is => 'ro',
lazy => 1,
default => sub {
my ($self) = @_;
my $open_file_param = "<:crlf";
IO::File->new( $self->path, $open_file_param )
or croak "Failed to open file '" . $self->path . "' : '$!'";
}
);
# File stat array
has _stat => (
is => 'lazy',
);
sub _build__stat {
my ($self) = @_;
my @stat = stat( $self->_fh );
return \@stat;
}
has index => (
is => 'rw',
lazy => 1,
builder => 1,
);
sub _build_index {
my ($self) = @_;
my $index = [];
( run in 0.785 second using v1.01-cache-2.11-cpan-71847e10f99 )