From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

#
# (c) Jan Gehring <jan.gehring@gmail.com>
#
# vim: set ts=2 sw=2 tw=0:
# vim: set expandtab:
=head1 NAME
Rex::FS::File - File Class
=head1 DESCRIPTION
This is the File Class used by I<file_write> and I<file_read>.
=head1 SYNOPSIS
use Rex::Interface::File;
my $fh = Rex::Interface::File->create('Local');
$fh->open( '<', 'filename' );
my $file = Rex::FS::File->new(fh => $fh);
$file->read($len);
$file->read_all;
$file->write($buf);
$file->close;
=head1 CLASS METHODS
=cut
package Rex::FS::File;
use strict;
our $VERSION = '1.7.0'; # VERSION
use constant DEFAULT_READ_LEN => 64;
=head2 new
This is the constructor. You need to set the filehandle which the object should work on
or pass a filename. If you pass a filehandle, it has to be a C<Rex::Interface::File::*>
object
my $fh = Rex::Interface::File->create('Local');
$fh->open( '<', 'filename' );
my $file = Rex::FS::File->new(fh => $fh);
Create a C<Rex::FS::File> object with a filename
# open a local file in read mode
my $file = Rex::FS::File->new(
filename => 'filename',
mode => 'r', # or '<'
type => 'Local',
);
# or shorter
my $file = Rex::FS::File->new( filename => 'filename' );
# open a local file in write mode
my $file = Rex::FS::File->new(
filename => 'filename',
mode => 'w', # or '>'
);
Allowed modes:
< read
r read
> write
w write
>> append
a append
For allowed C<types> see documentation of L<Rex::Interface::File>.
=cut
sub new {
my $that = shift;
my $proto = ref($that) || $that;
my $self = {@_};
my %modes = (
'w' => '>',
'r' => '<',
'a' => '>>',
'<' => '<',
'>' => '>',
'>>' => '>>',
);
if ( $self->{filename} ) {
$self->{mode} ||= '<';
my $mode = $modes{ $self->{mode} } || '<';
$self->{fh} = Rex::Interface::File->create( $self->{type} || 'Local' );
$self->{fh}->open( $mode, $self->{filename} );
}
bless( $self, $proto );
if ( ref $self->{fh} !~ m{Rex::Interface::File} ) {
die "Need an Rex::Interface::File object";
}
return $self;
}
sub DESTROY {
my ($self) = @_;
if ( ref $self->{'fh'} =~ m/^Rex::Interface::File/ ) {
$self->close if ( $self->{'fh'}->{'fh'} );
}
else {
$self->close if ( $self->{'fh'} );
}
}
=head2 write($buf)
Write $buf into the filehandle.
$file->write("Hello World");
=cut
sub write {
my ( $self, @buf ) = @_;
my $fh = $self->{fh};
if ( scalar(@buf) > 1 ) {
for my $line (@buf) {
$fh->write($line);
$fh->write($/);
}
}
else {
$fh->write( $buf[0] );
}
}
=head2 seek($offset)
Seek to the file position $offset.
Set the file pointer to the 5th byte.
$file->seek(5);
=cut
sub seek {
my ( $self, $offset ) = @_;
my $fh = $self->{'fh'};
$fh->seek($offset);
}
=head2 read($len)
Read $len bytes out of the filehandle.
my $content = $file->read(1024);
=cut
sub read {
my ( $self, $len ) = @_;
$len = DEFAULT_READ_LEN if ( !$len );
my $fh = $self->{'fh'};
return $fh->read($len);
}
=head2 read_all
Read everything out of the filehandle.
my $content = $file->read_all;
=cut
sub read_all {
my ($self) = @_;
my $all = '';
while ( my $in = $self->read() ) {
$all .= $in;
}
if (wantarray) {
return split( /\n/, $all );
}
return $all;
}
=head2 close
Close the file.
$file->close;
=cut
sub close {
my ($self) = @_;
my $fh = $self->{'fh'};
$fh->close;
}
1;