Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Check if a file exists and if not create it

by Wroof (Novice)
on Aug 20, 2014 at 20:51 UTC ( [id://1098161]=perlquestion: print w/replies, xml ) Need Help??

Wroof has asked for the wisdom of the Perl Monks concerning the following question:

Good morning Monks,

I am trying to write up a short test program to learn how to deal with files in Perl before I try and implement it into a program I have already written.

The idea of the test program is to open a file for appending and if the file does not exist create it and open it. The software in the end will be used to create a log in another program to help me track down an error that is occurring around once every 40-50 days.

What I have at the moment is just trying to open a file for appending/create the file, and then close the file before testing that it exists. This is all based on the IO:File Lib. The function $fh->open(">> test2.txt") always seams to return true even if the files does not exist and it does not create it either.

use IO::File; use strict; my $fh; sub test { my $filename = 'test2.txt'; unless (-f $filename) { print "File Exists!"; } else { print "File does not exist"; } } sub openFile { $fh = IO::File->new(); if ($fh->open(">> test2.txt")) { print "file open"; print <$fh>; $fh->close; } else { print "file failed to open"; } } openFile(); test();

Replies are listed 'Best First'.
Re: Check if a file exists and if not create it
by GotToBTru (Prior) on Aug 20, 2014 at 21:05 UTC

    Is there a reason to use IO::File instead of open $fh,'>>',$filename;?

    use strict; sub test { my $filename = 'test2.txt'; if (-f $filename) { print "File Exists!"; } else { print "File does not exist"; } } sub openFile { open my $fh, '>>', 'test2.txt'; print "file open!\n"; print $fh "The stuff I wanted to add to the end of the file.\n"; } test(); openFile(); test();

    Output:

    $: perl foo.pl File does not exist file open File Exists! $: cat test2.txt The stuff I wanted to add to the end of the file. $: perl foo.pl File Exists! file open File Exists! $: cat test2.txt The stuff I wanted to add to the end of the file. The stuff I wanted to add to the end of the file. $:
    1 Peter 4:10
      hey thanks for this. there was no reason I was using IO:File apart from what I found online in a tutorial. I found the problem was with where the program was creating the file 'C:\Users\user' instead of that I expected it to create it in the same directory the program is in.
Re: Check if a file exists and if not create it
by Your Mother (Archbishop) on Aug 20, 2014 at 21:50 UTC

    Learning is great. There are tons of modern packages that make this stuff really easy. Path::Tiny, for example, saved me a lot of headache just yesterday in a one-liners renaming a bunch of wget files that had query strings in the file names and couldn't be shared with a Windows user who needed them… I digress. One of many ways to do your task–

    perl -MPath::Tiny -le 'path("ohai")->touch'

      Gonna reply to myself while I remember the digression because it was one of those MY LORD, I LOVE PERL moments–

      find . -type f | perl -MPath::Tiny -lne '/^(.+?)\?/ && path($_)->move($1)'

      Finds names like /this/was-not-a/good.aspx?idea=for&a%20filename and turns them into /this/was-not-a/good.aspx.

Re: Check if a file exists and if not create it
by Laurent_R (Canon) on Aug 20, 2014 at 21:11 UTC
    Surprising. Opening a file in ">>" mode should create the file if it does not exist. And it does. Just opening the file without even doing anything to it (not trying to write anything) creates an empty file:
    $ perl -e 'open my $fh, ">>", "bar.txt" or die "can open file $!"; '
    is sufficient to create the bar.txt file:
    $ ls -l bar* -rw-r--r-- 1 Laurent None 0 20 Aug 23:05 bar.txt
Re: Check if a file exists and if not create it - use sysopen
by Discipulus (Canon) on Aug 21, 2014 at 11:56 UTC
    Hello Wroof and welcome,

    consider that there are many ways to do it in Perl...
    Normally a Perl programmer after years of using open meet also his father sysopen to have more granularity on existing or not file.
    >perl -e "use strict; use warnings;use Fcntl; my $fh; sysopen ($fh, 'f +ilefilefile.log', O_WRONLY|O_APPEND ) or die $!" No such file or directory at -e line 1. > > > > > > >ls filefilefile.log ls: filefilefile.log: No such file or directory > > >perl -e "use strict; use warnings;use Fcntl; my $fh; sysopen ($fh, 'f +ilefilefile.log', O_WRONLY|O_EXCL|O_CREAT ) or die $!" > > > > >ls filefilefile.log filefilefile.log > > > ------ Here are examples of open and sysopen in action. To open for reading: open(FH, "<", $path) or die $!; sysopen(FH, $path, O_RDONLY) or die $!; To open for writing, create a new file if needed, or else truncate an +old one: open(FH, ">", $path) or die $!; sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT, 0600) or die $!; To open for writing, create a new file, but that file must not previou +sly exist: sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT, 0600) or die $!; To open for appending, creating it if necessary: open(FH, ">>", $path) or die $!; sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT) or die $!; sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT, 0600) or die $!; To open for appending, where the file must exist: sysopen(FH, $path, O_WRONLY|O_APPEND) or die $!; To open for update, where the file must exist: open(FH, "+<", $path) or die $!; sysopen(FH, $path, O_RDWR) or die $!; To open for update, but create a new file if necessary: sysopen(FH, $path, O_RDWR|O_CREAT) or die $!; sysopen(FH, $path, O_RDWR|O_CREAT, 0600) or die $!; To open for update, where the file must not exist: sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT) or die $!; sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT, 0600) or die $!; We use a creation mask of 0600 here only to show how to create a priva +te file. The argument is normally omitted.

    HtH
    L*

    UPDATE: some docs are missing

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      i get bare word error when i complie the script using flags O_RDWR or others, what could be the reason ?

        have you imported the module with use Fcntl ? see Fcntl

        L*

        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Check if a file exists and if not create it
by Aldebaran (Curate) on Aug 21, 2014 at 21:59 UTC

    I believe that checking to see whether a file exists before creating it can create a race condition. I've been told that the better way to do this is to create the file, and deal with the exception thrown if the file already exists.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1098161]
Front-paged by GotToBTru
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (5)
As of 2024-04-19 10:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found