Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I delay creation of a text file until I actually write a line to it? (lazy creation)

Tags:

file

perl

I have a perl script that append text on a file :

open (EXFILE, ">>$outFile");

at the moment of the open an empty file is created, i want to avoid this. I want that the file will be created only the first time that a line is written to the file handle :

print EXFILE $line 

If nothing is written to the file handle the file should not be created ...

Is it possible ? How ?

like image 719
aleroot Avatar asked Feb 23 '23 03:02

aleroot


2 Answers

Create a sub that does the opening for you.

sub myappend {
    my ($fname, @args) = @_;
    open my $fh, '>>', $fname or die $!;
    print $fh @args;
    close $fh or die $!;
}

myappend($outfile, $line);

Alternatively, instead of printing, push onto an array and wait until the end to print.

while ( ... ) {
    push @print, $line;
}

if (@print) {
    open my $fh, '>>', $outfile or die $!;
    print $fh @print;
}

Or, for multiple files

while ( ... ) {
    push @{$print{$outfile}}, $line;
}

for my $key (%print) {
    open my $fh, '>>', $key or die $!;
    print $fh @{$print{$key}};
}
like image 160
TLP Avatar answered Apr 29 '23 20:04

TLP


I was thinking, what would be the simplest object that would print out to the file when it was about to be destroyed.

package My::Append; use strict; use warnings;

sub new {
  my($class,$filename) = @_;
  my $self = bless {
    filename => $filename,
  }, $class;
  return $self;
}

sub append{
  my $self = shift;
  push @{ $self->{elem} }, @_;
  return scalar @_;
}

sub append_line{
  my $self = shift;
  push @{ $self->{elem} }, map { "$_\n" } @_;
  return scalar @_;
}

sub filename{
  my($self) = @_;
  return $self->{filename};
}

sub DESTROY{
  my($self) = @_;
  open my $fh, '>>', $self->filename or die $!;
  print {$fh} $_ for @{ $self->{elem} };
  close $fh or die $!;
}

Used like this:

{
  my $app = My::Append->new('test.out');
  $app->append_line(qw'one two three');
} # writes to file here
like image 36
Brad Gilbert Avatar answered Apr 29 '23 20:04

Brad Gilbert