How to read file in Perl and if it doesn't exist create it?
Asked Answered
M

4

8

In Perl, I know this method :

open( my $in, "<", "inputs.txt" );

reads a file but it only does so if the file exists.

Doing the other way, the one with the +:

open( my $in, "+>", "inputs.txt" );

writes a file/truncates if it exists so I don't get the chance to read the file and store it in the program.

How do I read files in Perl considering if the file exists or not?

Okay, I've edited my code but still the file isn't being read. The problem is it doesn't enter the loop. Anything mischievous with my code?

open( my $in, "+>>", "inputs.txt" ) or die "Can't open inputs.txt : $!\n";
while (<$in>) {
    print "Here!";
    my @subjects    = ();
    my %information = ();
    $information{"name"}     = $_;
    $information{"studNum"}  = <$in>;
    $information{"cNum"}     = <$in>;
    $information{"emailAdd"} = <$in>;
    $information{"gwa"}      = <$in>;
    $information{"subjNum"}  = <$in>;
    for ( $i = 0; $i < $information{"subjNum"}; $i++ ) {
        my %subject = ();
        $subject{"courseNum"} = <$in>;
        $subject{"courseUnt"} = <$in>;
        $subject{"courseGrd"} = <$in>;
        push @subjects, \%subject;
    }
    $information{"subj"} = \@subjects;
    push @students, \%information;
}
print "FILE LOADED.\n";
close $in or die "Can't close inputs.txt : $!\n";
Meerkat answered 16/9, 2014 at 5:43 Comment(2)
You could also check for the existence first if (-e "/filepath/file"){…}Charitacharitable
Instead of coding your own serializer and parser for file based data storage, I would recommend using either YAML or JSON to do most of that work for you.Mimesis
A
13

Use the proper test file operator:

use strict;
use warnings;
use autodie;

my $filename = 'inputs.txt';
unless(-e $filename) {
    #Create the file if it doesn't exist
    open my $fc, ">", $filename;
    close $fc;
}

# Work with the file
open my $fh, "<", $filename;
while( my $line = <$fh> ) {
    #...
}
close $fh;

But if the file is new (without contents), the while loop won't be processed. It's easier to read the file only if the test is fine:

if(-e $filename) {
   # Work with the file
   open my $fh, "<", $filename;
   while( my $line = <$fh> ) {
      #...
   }
   close $fh;
}
Audiogenic answered 16/9, 2014 at 6:21 Comment(1)
Thank you! Learned something new with the -e and it's now working.Meerkat
R
5

You can use +>> for read/append, creates the file if it doesn't exist but doesn't truncate it:

open(my $in,"+>>","inputs.txt");
Rhoads answered 16/9, 2014 at 5:52 Comment(0)
C
1

The solution proposed in the acceptet answer can be written with less (better readable) code, using the File::Touch library from https://www.cpan.org

use File::Touch;

my $file = 'a_file.txt';

touch($file) unless(-e $file);
Clubhaul answered 3/7, 2023 at 12:5 Comment(1)
You could even omit the unless(-e $file) if you don't mind updating the timestamp if the file exists already.Elmira
D
0

First check whether the file exists or not. Check the sample code below :

#!/usr/bin/perl
use strict;
use warnings;
my $InputFile = $ARGV[0];
if ( -e $InputFile ) {
    print "File Exists!";
    open FH, "<$InputFile";
    my @Content = <FH>;
    open OUT, ">outfile.txt";
    print OUT @Content;
    close(FH);
    close(OUT);
} else {
    print "File Do not exists!! Create a new file";
    open OUT, ">$InputFile";
    print OUT "Hello World";
    close(OUT);
}
Disavowal answered 16/9, 2014 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.